//
//  Data_Model.m
//  MacStockApp
//
//  Created by 英傑 翁 on 12/2/13.
//  Copyright (c) 2012年 翁英傑. All rights reserved.
//

 

#import "Data_Model.h"
#import "NSString+HTML.h"
#import "SourceListItem.h"
#import "CommonFunction.h"
#import "GBTableColumnHeader.h"
#import "GBTableColumnHeader_basicSqlite.h"
#import "GBTableColumnHeader_quote.h"
#import "GBTableColumnHeader_2Row3Row.h"
#import "GBTableColumnHeader_node.h" 
#import "GBTableColumnHeader_position.h"  
#import "GBTableColumnHeader_position_bottom_sumaverage.h"  
#import "GBTableColumnHeader_Indicator.h"  
#import "GBTableColumnHeader_signal.h"  
#import "GBTableColumnHeader_ObjectOtherKey.h"  
#import "GBTableColumnHeader_key.h"
#import "GBall.h"
#import "Optimize_Para.h"
#import "GBCalculationMethod_selfIndicator.h"
#import "RLCalculationMethod.h"
#import "File_Name_Path.h"

NSString * const NOT_output_chart = @"NOT_output_chart";
NSString * const NOT_quote_reload = @"NOT_quote_reload";
NSString * const NOT_quote_begin = @"NOT_quote_begin";
NSString * const NOT_his_reload_APP1_Start_WindowController = @"NOT_his_reload_APP1_Start_WindowController";
NSString * const NOT_his_reload_XXsheet_sort = @"NOT_his_reload_XXsheet_sort";
NSString * const NOT_his_reload_XXsheet_output = @"NOT_his_reload_XXsheet_output";
NSString * const NOT_his_begin_APP1_Start_WindowController = @"NOT_his_begin_APP1_Start_WindowController";
NSString * const NOT_quote_begin_XXsheet_sort = @"NOT_quote_begin_XXsheet_sort";
NSString * const NOT_quote_begin_XXsheet_output = @"NOT_quote_begin_XXsheet_output";

#define Max_Qote_Every_Load_url 20             //每次上網取得資料的代碼數目

#define Max_OperationQueue_yahooMobile 3            //報價執行緒最大使用量
#define Max_OperationQueue_yahooWeb    3            //報價執行緒最大使用量
#define Max_OperationQueue_google      3            //報價執行緒最大使用量
#define Max_OperationQueue_bloomberg   3           //報價執行緒最大使用量

#define Max_OperationQueue_his_data 3 //歷史資料下載時執行緒 最大使用量
#define Max_Diff_Hour_To_Get_History_Data 2 //設定兩個小時內取出歷史資料後都不用檢查是否要在下載一次

//按照上面的算法 下載最大的上限為 1000檔股票

@implementation Data_Model
@synthesize productName;
@synthesize queue_quote;
@synthesize code_array_Yahoo_Google;
@synthesize data_object_arrary;
@synthesize Para_SLT_Paraent_Array;
@synthesize datasource;
@synthesize unstart_code_array_his_data;
@synthesize Para_SLT_system;
@synthesize Para_SLT_watchlist;
@synthesize Para_SLT_watchlist_1;
//@synthesize watchlist_filename;
@synthesize table_column_object_array;
@synthesize have_to_calculate_history_serial_indicator_signal;
@synthesize RLChartMenuItem_object_array;
@synthesize temp_all_sub_node;
@synthesize tree_sort_data;
@synthesize tree_output_data_to_chart;
@synthesize tree_output_data_to_excel;
@synthesize databasePath_nsame;
@synthesize is_on_Optimize_DataModel;
@synthesize is_on_TreeSort_DataModel;
@synthesize Para_SLT_optimize;
@synthesize optimize_method;
@synthesize is_on_output_to_chart_DataModel;
@synthesize is_on_output_to_excel_DataModel;
@synthesize calculate_property_all;

#pragma mark -
#pragma mark 初始設定

+(void)init_property  {
    NSString *DisplayName;
    DisplayName=[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
    
    NSString *target_ProductName= [NSString stringWithFormat:@"Target_%@",DisplayName] ;
    
    
    NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
    
    //1.欄位是否有顯示範例
    
    //標記Target:是否強迫顯示範例欄位
    if (([target_ProductName isEqualToString:Target_wStock] || [target_ProductName isEqualToString:Target_wStockRT])) {
        //標記：是否強迫顯示範例欄位 程式啟動初始化
        [prefs setObject:[NSNumber numberWithBool:NO]  forKey: Defaults_Table_column_show_example ];
        
    }
    else{
    
        [prefs setObject:[NSNumber numberWithBool:YES]  forKey: Defaults_Table_column_show_example ];
        
    }
    
   
    
    //2.歷史資料序列存放的方法
    /*
     1.Defaults_History_Serial_Method_Memory 利用電腦記憶體存時間序列資料 優點：快速 缺點：耗損可用記憶體
     2.Defaults_History_Serial_Method_plist  另用硬碟存時間序列資料且可以看到每筆詳細資料
     3.Defaults_History_Serial_Method_arch   另用硬碟存時間序列資料但因為是壓縮檔，不可以看到每筆詳細資料
     */
    [prefs setObject:Defaults_History_Serial_Method_Memory forKey: Defaults_History_Serial_Method ];
    
    //3.系統群組下有哪幾個的國家或交易所
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
    [prefs setObject:[NSArray arrayWithObjects: @"IND_1",@"TW_1" ,nil] forKey: Defaults_System_CountryOrExchange ];
    
#else
     //[prefs setObject:[NSArray arrayWithObjects:  @"TW_1",@"IND_1", nil] forKey: Defaults_System_CountryOrExchange ];
    
     [prefs setObject:[NSArray arrayWithObjects:  @"IND_1", nil] forKey: Defaults_System_CountryOrExchange ];       
#endif
    
    
    
    
        //@"IND_1", @"US_1 ,@"HK_1",@"TW_1"
    
    //4.報價更新間隔
    [prefs setObject:[NSNumber numberWithFloat:30.0] forKey: Defaults_timer_refreshQuote ];
    
    //5.是否自動更新報價
    //即時報價 檢查如果是第一次就是採用自動報價
    if (![prefs objectForKey:ToolbarItem_RealTime]) {
        [prefs setObject:[NSNumber numberWithBool:YES]  forKey: ToolbarItem_RealTime ];
    }  
    
    //6.是否以調整後收盤價當作收盤價
    [prefs setObject:[NSNumber numberWithBool:YES]  forKey: Defaults_isUse_AdjClose ];
    
    //移動查價
    [prefs setObject:[NSNumber numberWithBool:NO]  forKey: ToolbarItem_MoveCheck ];
    
        
    [prefs synchronize];
}

//初始設定資料源
+(void)init_datasource{
   
    NSString *DisplayName;
    DisplayName=[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
    
    NSString *target_ProductName= [NSString stringWithFormat:@"Target_%@",DisplayName] ;
    
    
    
    NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
  
    
    if ([prefs objectForKey:@"id_資料源"]==nil) {
       
        //標記Target:初次資料源設定
        if ([target_ProductName isEqualToString:Target_PSC]) {
            [prefs setObject:id_Bloomberg  forKey:@"id_資料源"];
            [prefs synchronize];
            
        }
        else if ( [target_ProductName isEqualToString:Target_wStock] || [target_ProductName isEqualToString:Target_wStockRT] ) {
            [prefs setObject:id_MultiServer_GY  forKey:@"id_資料源"];
            [prefs synchronize];
            
        }
        else if ([target_ProductName isEqualToString:Target_iPad]) {
            [prefs setObject:id_MultiServer_GY  forKey:@"id_資料源"];
            [prefs synchronize];
            
        }
        else{
            [prefs setObject:id_MultiServer_GY  forKey:@"id_資料源"];
            [prefs synchronize];
        } 
        
                        
    }
    
    //初始化設定即時報價訂閱都到期
    if ([prefs objectForKey:Real_Time_Subscription_isExpire]==nil) {
        
        //標記Target:InAppPurchase 初始化是否一開始就是即時報價訂閱已經到期了
        if ([target_ProductName isEqualToString:Target_wStockRT]){
            
            [prefs setObject:[NSNumber numberWithBool:YES]  forKey:Real_Time_Subscription_isExpire];
        }
        else{
            
            [prefs setObject:[NSNumber numberWithBool:NO]  forKey:Real_Time_Subscription_isExpire];
        }
        
        
        [prefs synchronize];
        
    }
        
    
    
} 
//初始路徑
+(void)init_path{
    //建立必要的目錄 並且將路徑資料存到default.plist
    {
        //Documents
        {
            NSArray *paths_Document = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
            NSString *path_Document = [paths_Document objectAtIndex:0];             
            
            NSString *BundleIdentifier;
            BundleIdentifier=[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"];
            
            NSLog(@"CFBundleIdentifier=%@",BundleIdentifier);
            
            //在Document 下面再增加一個資料夾
            path_Document=[path_Document stringByAppendingPathComponent:BundleIdentifier];
            
            
            
            //檔案路徑名稱建立
          
            //a.自設群組路徑
            NSString *Para_SLT_watchlist_System_Path =[path_Document stringByAppendingPathComponent:@"Para_SLT_watchlist_System"];
            
            NSString *Para_SLT_watchlist_Path =[path_Document stringByAppendingPathComponent:@"Para_SLT_watchlist"];       
            
            NSString *Table_column_Path =[path_Document stringByAppendingPathComponent:@"Table_column"];
            NSString *Table_column_group_Path =[path_Document stringByAppendingPathComponent:@"Table_column_group"];
            NSString *Calculate_method_Path =[path_Document stringByAppendingPathComponent:@"RLChartMenuItem"];
            
           NSString *Node_TO_Chart_Data_Path =[path_Document stringByAppendingPathComponent:@"Node_TO_Chart_Data"];            
            
            
            
            
            
            //3.建立路徑 檔案管理
            {
                NSFileManager *filemanager=[NSFileManager defaultManager];
                
                BOOL isDir;        
                isDir=YES;
                
                //a.系統群組路徑
                if (![filemanager fileExistsAtPath:Para_SLT_watchlist_System_Path isDirectory:&isDir]) {
                    
                    [filemanager createDirectoryAtPath:Para_SLT_watchlist_System_Path withIntermediateDirectories:YES attributes:nil error:nil];
                    
                    
                }                 
                
                //b.自設群組路徑
                if (![filemanager fileExistsAtPath:Para_SLT_watchlist_Path isDirectory:&isDir]) {
                    
                    [filemanager createDirectoryAtPath:Para_SLT_watchlist_Path withIntermediateDirectories:YES attributes:nil error:nil];
                    
                   
                }   
                
                //c.欄位資料路徑
                if (![filemanager fileExistsAtPath:Table_column_Path isDirectory:&isDir]) {
                    
                    [filemanager createDirectoryAtPath:Table_column_Path withIntermediateDirectories:YES attributes:nil error:nil];
                }
                //d.欄位群組資料路徑
                if (![filemanager fileExistsAtPath:Table_column_group_Path isDirectory:&isDir]) {
                    
                    [filemanager createDirectoryAtPath:Table_column_group_Path withIntermediateDirectories:YES attributes:nil error:nil];
                }
                
                //e.歷史計算方法資料路徑
                if (![filemanager fileExistsAtPath:Calculate_method_Path isDirectory:&isDir]) {
                    
                    [filemanager createDirectoryAtPath:Calculate_method_Path withIntermediateDirectories:YES attributes:nil error:nil];
                }
                
                //f.走勢圖選項資料 存放資料存放位置
                if (![filemanager fileExistsAtPath:Node_TO_Chart_Data_Path isDirectory:&isDir]) {
                    
                    [filemanager createDirectoryAtPath:Node_TO_Chart_Data_Path withIntermediateDirectories:YES attributes:nil error:nil];
                }
            }
            //將路徑名稱存到Default
            {
                NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];	                    
                
                {
                    //a.歷史資料檔案路徑
                    [prefs setObject:Para_SLT_watchlist_System_Path  forKey: Defaults_Path_Para_SLT_watchlist_system ];
                    
                    //b.歷史資料檔案路徑
                    [prefs setObject:Para_SLT_watchlist_Path  forKey: Defaults_Path_Para_SLT_watchlist ];
                    
                    
                    //c.欄位資料路徑        
                    [prefs setObject:Table_column_Path  forKey: Defaults_Path_Table_column ];
                    //d.欄位資料路徑
                    [prefs setObject:Table_column_group_Path forKey: Defaults_Path_Table_column_group ];
                    
                    //e.歷史計算方法資料路徑
                    [prefs setObject:Calculate_method_Path  forKey: Defaults_Path_Chart_Menu_Item ];                     
                    
                    //f.走勢圖選項資料 存放資料存放位置
                    [prefs setObject:Node_TO_Chart_Data_Path  forKey: Defaults_Path_Node_TO_Chart_Data ];
                    
                }
                
                [prefs synchronize];          
            }
            
            
            
            
        }
        
        
        //Catches
        {
            //1.Caches路徑 放在catch路徑 有可被刪除
            NSArray *paths_Caches = NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask,YES);
            NSString *Path_Caches = [paths_Caches objectAtIndex:0];
            
            NSString *BundleIdentifier;
            BundleIdentifier=[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"];
            
            NSLog(@"CFBundleIdentifier=%@",BundleIdentifier);
            
            //在Caches 下面再增加一個資料夾
            Path_Caches=[Path_Caches stringByAppendingPathComponent:BundleIdentifier];
            
            NSLog(@"Path_Caches=%@",Path_Caches);            
            
            //檔案路徑名稱建立
            //a.歷史檔案路徑
            NSString *History_data_serial_Path =[Path_Caches stringByAppendingPathComponent:@"HistoryData"];       
            //b.模型資料檔案路徑        
            NSString *Datamodel_data_serial_Path =[Path_Caches stringByAppendingPathComponent:@"DatamodelData"];         
            //c.系統資料檔案路徑        
            NSString *Para_SLT_system_Path =[Path_Caches stringByAppendingPathComponent:@"ParaSLTsystemData"];         
            //d.sqlite檔案路徑        
            NSString *Sqlite_Path =[Path_Caches stringByAppendingPathComponent:@"Sqlite"];         
            //e.History_Catches檔案路徑        
            NSString *History_Catches_data_serial_Path =[Path_Caches stringByAppendingPathComponent:@"History_Catches"];          
            //f.XQ_Dairly檔案路徑
            NSString *XQ_Dairly_Path =[Path_Caches stringByAppendingPathComponent:@"XQ_Dairly"];
            
             NSLog(@"sqlite檔案路徑=%@",Sqlite_Path);
            
            //3.建立路徑 檔案管理
            {
                NSFileManager *filemanager=[NSFileManager defaultManager];
                
                BOOL isDir;        
                isDir=YES;
                
                //a.歷史檔案路徑
                if (![filemanager fileExistsAtPath:History_data_serial_Path isDirectory:&isDir]) {
                    
                    [filemanager createDirectoryAtPath:History_data_serial_Path withIntermediateDirectories:YES attributes:nil error:nil];
                }   
                
                //b.模型資料檔案路徑
                if (![filemanager fileExistsAtPath:Datamodel_data_serial_Path isDirectory:&isDir]) {
                    
                    [filemanager createDirectoryAtPath:Datamodel_data_serial_Path withIntermediateDirectories:YES attributes:nil error:nil];
                }  
                //c.系統資料檔案路徑
                if (![filemanager fileExistsAtPath:Para_SLT_system_Path isDirectory:&isDir]) {
                    
                    [filemanager createDirectoryAtPath:Para_SLT_system_Path withIntermediateDirectories:YES attributes:nil error:nil];
                }                  
                //d.sqlite檔案路徑
                if (![filemanager fileExistsAtPath:Sqlite_Path isDirectory:&isDir]) {
                    
                    [filemanager createDirectoryAtPath:Sqlite_Path withIntermediateDirectories:YES attributes:nil error:nil];
                }  
                //e.History_Catches檔案路徑
                if (![filemanager fileExistsAtPath:History_Catches_data_serial_Path isDirectory:&isDir]) {
                    
                    [filemanager createDirectoryAtPath:History_Catches_data_serial_Path withIntermediateDirectories:YES attributes:nil error:nil];
                }                  
                else {
                    
                    //表示裡面已經可能有舊的暫存歷史資料檔 全部刪除 
                    NSDirectoryEnumerator *dirEnumerator = [filemanager enumeratorAtPath:History_Catches_data_serial_Path ]; 
                    NSString *currPath; 
                    NSError *error;
                    
                    
                    //循環刪除
                    while (currPath = [dirEnumerator nextObject]) 
                    { 
                        
                        NSString *delpath;
                        delpath=[History_Catches_data_serial_Path stringByAppendingPathComponent:currPath];
                        [filemanager removeItemAtPath:delpath error:&error];                        
                        
                        
                    }
                    
                }
                //f.XQ_Dairly_Path檔案路徑
                if (![filemanager fileExistsAtPath:XQ_Dairly_Path isDirectory:&isDir]) {
                    
                    [filemanager createDirectoryAtPath:XQ_Dairly_Path withIntermediateDirectories:YES attributes:nil error:nil];
                }
                
                
            }
            
            
            //將路徑名稱存到Default
            {
                NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];	                    
                
                {
                    //a.歷史資料檔案路徑        
                    [prefs setObject:History_data_serial_Path  forKey: Defaults_Path_HistoryData ];                    
                    //b.模型資料檔案路徑
                    [prefs setObject:Datamodel_data_serial_Path  forKey: Defaults_Path_DatamodelData ];             
                    //c.系統資料檔案路徑
                    [prefs setObject:Para_SLT_system_Path  forKey: Defaults_Path_Para_SLT_system_Data ];                  
                    //d.系統資料檔案路徑
                    [prefs setObject:Sqlite_Path  forKey: Defaults_Path_Sqlite_Data ];  
                    
                    //e.History_Catches檔案路徑
                    [prefs setObject:History_Catches_data_serial_Path  forKey: Defaults_Path_HistoryData_Catches ];                     
                    
                    //f.History_Catches檔案路徑
                    [prefs setObject:XQ_Dairly_Path  forKey: Defaults_Path_XQ_Dairly ];
                    
                }
                
                [prefs synchronize];          
            }
            
        }
        
        
    }
}
//初始屬性資料

#pragma mark -
#pragma mark 初始設定與消滅

- (id)init_data:(NSString *)ds system_exchange:(NSArray *) system_country_array {
	
    self=[super init];
    
    if(self)
	{
       
        //設置商品 target_ProductName
        {
            
            NSString *DisplayName;
            DisplayName=[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
            
            target_ProductName=[[NSString stringWithFormat:@"Target_%@",DisplayName] retain];
            [self setProductName:DisplayName];
            
        }
        
        
        
        quote_Queue_total_count=0;
        hisdata_Queue_total_count=0;
        
        //設定資料源
        datasource=ds;        
        
        //記憶體初始化
        data_object_arrary=[[NSMutableArray alloc] init];
        
        queue_quote = [[NSOperationQueue alloc] init];  
        
        
        queue_optimize_para  = [[NSOperationQueue alloc] init];       
        
        queue_his_data = [[NSOperationQueue alloc] init];          
        
        unstart_code_array_his_data=[[NSMutableArray alloc] init];        
        
        Para_SLT_Paraent_Array = [[NSMutableArray alloc] init];  
        
        code_array_Yahoo_Google=[[NSMutableArray alloc] init];
        
        
        //table_column_object_array=[[RLTableColumnHeader alloc] init_datasource:datasource];
        [self setTable_column_object_array:[[[RLTableColumnHeader alloc] init_datasource:datasource] autorelease]];
        
        
        [self setRLChartMenuItem_object_array:[[[RLChartMenuItem alloc] init_datasource:datasource] autorelease] ];
        
         
        [self setIs_on_Optimize_DataModel:[NSNumber numberWithBool:NO]];
       
        //sqlite 資料庫複製
        {
            
            //sqlite 檔名
            NSString *fullfilename;
            fullfilename=[NSString stringWithFormat:@"%@.sqlite3",[File_Name_Path file_name_sqlite]];
            
            NSString *fullfilename_no_sqlite3;
            fullfilename_no_sqlite3=[File_Name_Path file_name_sqlite];
            
            NSString *sqlite3=@"sqlite3";
            
            //sqlite 檔案路徑
            NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
            NSString *Path_Sqlite_Data  ;
            Path_Sqlite_Data=[prefs objectForKey:Defaults_Path_Sqlite_Data];
            
            
            //設定資料庫位置名稱
            [self setDatabasePath_nsame:[Path_Sqlite_Data stringByAppendingPathComponent: fullfilename]];
           
            
            NSFileManager *fileManager = [NSFileManager defaultManager];
            BOOL success = [fileManager fileExistsAtPath:databasePath_nsame];
            
            //取得資料庫在資源裏面的路徑
            NSString *resourcePath= [[NSBundle mainBundle] pathForResource:fullfilename_no_sqlite3 ofType:sqlite3];
            //若已經存在則不用從應用程式的資源檔內拷貝到 Documents
            if( !success ){
                NSLog(@"sqlite3 資料庫 原始位置=%@",resourcePath);
                NSLog(@"拷貝 sqlite3 資料庫 位置=%@",databasePath_nsame);
                
                //如果沒有拷貝到執行的位置
                
                //將資料庫檔案從resourcePath 拷貝到theInstance.databasePath
                [fileManager copyItemAtPath:resourcePath toPath:databasePath_nsame error:nil];
                
               
            }
            else{
                NSLog(@"sqlite3 資料庫 原始位置=%@",resourcePath);
                NSLog(@"已經有sqlite3 資料庫 位置=%@",databasePath_nsame);
                
            }
        
        }
        
        
        //樹狀資料建置        
        { 
                               
            
            //系統群組 使用程式碼產生資料夾與文件
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
            //原本的模式
            
            Para_SLT_system = [SourceListItem itemWithTitle:Node_System identifier:Node_System];
            {
                //此陣列主要作用是從檔案取出陣列
                NSArray *read_array;
                
                //建立系統陣列 並且將plist檔案儲存
                read_array=[self create_write_countrys_node:system_country_array];
                
                //將陣列結構轉成樹狀結構
                [self array_convert_to_tree:read_array paraobject:Para_SLT_system];
                
                //將樹狀結構加到承載母節點的陣列上
                [Para_SLT_Paraent_Array addObject:Para_SLT_system];
                
                
            }
   
            
#else
            //母節點 Para_SLT_system
            {
                //a取出自選群組的路徑與名稱
                NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
                NSString *_Path=[prefs objectForKey:Defaults_Path_Para_SLT_watchlist_system];
                NSString *_Name=[File_Name_Path file_name_Watchlist_System];
                
                
                //b.設定自選群組名稱
                Para_SLT_system =[self create_Top_Para_SourceListItem:Node_System identifier:Node_System path:_Path name:_Name];
                
                //c.將樹狀結構加到母
                [Para_SLT_Paraent_Array addObject:Para_SLT_system];
            }         
            
            
#endif 
             
            
            //自設群組 從檔案內取出陣列之後在轉成樹狀結構
            //母節點 Defaults_Path_Para_SLT_watchlist
            {
                //a取出自選群組的路徑與名稱
                NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
                NSString *_Path=[prefs objectForKey:Defaults_Path_Para_SLT_watchlist];
                NSString *_Name=[File_Name_Path file_name_Watchlist];
                
                
                //b.設定自選群組名稱
                Para_SLT_watchlist =[self create_Top_Para_SourceListItem:Node_Custom identifier:Node_Custom path:_Path name:_Name];
                
                //c.將樹狀結構加到母
                [Para_SLT_Paraent_Array addObject:Para_SLT_watchlist];
            }             
      
        
        }
                
        //計算方法整合
        [self combine_calculate_method_table_chart ];       
    }
	
	return self;
}

-(SourceListItem *)create_Top_Para_SourceListItem:(NSString *)_title identifier:(NSString *)_identifier path:(NSString *)_path name:(NSString *)_name{
    
    
    SourceListItem *_watchlist = [SourceListItem itemWithTitle:_title identifier:_identifier];
    {
         
       
        NSString *filename_plist=[NSString stringWithFormat: @"%@.plist",_name];
        
        NSString * watchlist_filepath= [_path stringByAppendingPathComponent:filename_plist]  ;
        
        
        //此陣列主要作用是從檔案取出陣列
        NSArray *read_array;
        
        NSLog(@"自選群組檔案位置＝%@",watchlist_filepath );
        
        
        //檢查是否已經有自選群組名單檔案 如果沒有 就是從資源檔案取出 並將它拷貝到catch
        {
            
            NSFileManager *fileManager = [NSFileManager defaultManager];
            BOOL success = [fileManager fileExistsAtPath:watchlist_filepath];
            //判斷是否有觀察名單檔案
            if (!success) {
                NSLog(@"沒有自選群組檔案");
                //1.取得資料庫在資源裏面的路徑
                NSString *resourcePath= [[NSBundle mainBundle] pathForResource:_name ofType:@"plist"];
                //檢查boundle是否有此file
                {
                    BOOL success1 = [fileManager fileExistsAtPath:resourcePath];
                    if (!success1) {
                        
                        //退出離開
                        exit(0);
                        
                        
                    }
                    
                }
                
                NSLog(@"Para_SLT_watchlist.plist 在資源區的檔案位置＝%@",resourcePath);
                //2.將資源區的資料拷貝到要使用的區域
                [fileManager copyItemAtPath:resourcePath toPath: watchlist_filepath   error:nil];
                
                
            }
            else {
                NSLog(@"有自選群組檔案");
                //不做任何動作
            }
        }
        
        
        //取檔
        read_array=[NSArray arrayWithContentsOfFile:watchlist_filepath];
        
        //從檔案取出的陣列結構轉成樹狀結構
        [self array_convert_to_tree:read_array paraobject:_watchlist];
        
        
        
        
    }
    
    
    return _watchlist;



}

- (void)dealloc{
    
    [target_ProductName release];
    
    [data_object_arrary release];
    data_object_arrary=nil;
    
    [queue_quote release];
    queue_quote = nil;
    
    [queue_his_data release];
    queue_his_data = nil;
    
     [Para_SLT_Paraent_Array release];
     Para_SLT_Paraent_Array=nil;
    
    
    [code_array_Yahoo_Google  release];
    code_array_Yahoo_Google=nil;
    
    [super dealloc];
    
    
}

#pragma mark -
#pragma mark NSCoder
//標記：壓縮資料 壓縮協定方法實作
- (void)encodeWithCoder:(NSCoder *)aCoder{
   
    [aCoder encodeObject:datasource forKey:@"Data_Model_datasource"]; 
    [aCoder encodeObject:data_object_arrary forKey:@"Data_Model_data_object_arrary"];  
    [aCoder encodeObject:unstart_code_array_his_data forKey:@"Data_Model_unstart_code_array_his_data"];  
    
    [aCoder encodeObject:Para_SLT_system forKey:@"Data_Model_Para_SLT_system"];     
    [aCoder encodeObject:Para_SLT_watchlist forKey:@"Data_Model_Para_SLT_watchlist"]; 
    
    [aCoder encodeObject:Para_SLT_Paraent_Array forKey:@"Data_Model_Para_SLT_Paraent_Array"]; 
    
    //[aCoder encodeObject:watchlist_filename forKey:@"Data_Model_watchlist_filename"];
    
    [aCoder encodeObject:table_column_object_array forKey:@"Data_Model_table_column_object_array"];         
    
}
- (id)initWithCoder:(NSCoder *)aDecoder{
    self=[super init];
    if (self) {
        
        datasource=[[aDecoder decodeObjectForKey:@"Data_Model_datasource"] retain]; 
        data_object_arrary=[[aDecoder decodeObjectForKey:@"Data_Model_data_object_arrary"] retain]; 
        unstart_code_array_his_data=[[aDecoder decodeObjectForKey:@"Data_Model_unstart_code_array_his_data"] retain]; 
        
        Para_SLT_system=[[aDecoder decodeObjectForKey:@"Data_Model_Para_SLT_system"] retain];         
           
        Para_SLT_watchlist=[[aDecoder decodeObjectForKey:@"Data_Model_Para_SLT_watchlist"] retain];   
        Para_SLT_Paraent_Array=[[aDecoder decodeObjectForKey:@"Data_Model_Para_SLT_Paraent_Array"] retain];         
        //watchlist_filename=[[aDecoder decodeObjectForKey:@"Data_Model_watchlist_filename"] retain];
        
        table_column_object_array=[[aDecoder decodeObjectForKey:@"Data_Model_table_column_object_array"] retain];         
        
        
        //標記：壓縮資料 init注意事項        
        //非常重要 要讓initWithCoder的記憶體結構與init內相同
        queue_quote = [[NSOperationQueue alloc] init];  
        queue_his_data = [[NSOperationQueue alloc] init];          
        
    }
    return self;
}

 
 
#pragma mark -
#pragma mark 樹狀結構與陣列轉換存取
//將樹狀結構轉成陣列

-(NSMutableArray *)tree_convert_to_array:(NSArray *)treearray{
    
    NSMutableArray *outputarrary;
    outputarrary=[[NSMutableArray alloc] init];
    
    for (SourceListItem *p in  treearray) {
        
        //標記:要增加點結構NODE的資料時，要增加的程式碼        
        NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithCapacity:2];
        [dic setObject:[p identifier] forKey:Node_identifier];
        [dic setObject:[p title] forKey:Node_title]; 
        [dic setObject:[p icon]   forKey:Node_icon];   
        [dic setObject:[p isUseForGroup]   forKey:Node_isUseForGroup];           
        [dic setObject: [p badgeValue]  forKey:Node_badgeValue];
        //請特別注意 此段會有記憶體遺漏 但是不可以處理掉 因為這裡是樹狀回圈 如果處理的話 就會當機
        //Node_Array_StockData        
        {
            //只有取出Data_Object 裡的table_data 儲存
             NSMutableArray *temp_table_object=   [[[NSMutableArray alloc] init] autorelease]    ;
            if ([[p get_allcode_from_data_array_object] count]>0) {
                for (NSMutableDictionary *dma in [p get_allcode_from_data_array_object] ) {
                    
                    NSMutableDictionary *temp_dic=[[NSMutableDictionary alloc] init];
                    {
                        //標記：報價-欄位資料來源為sqlite資料檔案中輸入 7.存檔 新增一檔股票                        
                        
                                                
                        
                         [temp_dic setObject:[dma objectForKey:DB_object_sqlite_basic_class] forKey:DB_object_sqlite_basic_class];                        
                        
                        [temp_dic setObject:[dma objectForKey:DB_object_sqlite_basic_code] forKey:DB_object_sqlite_basic_code];
                        
                        [temp_dic setObject:[dma objectForKey:DB_object_sqlite_basic_code_Bloomberg] forKey:DB_object_sqlite_basic_code_Bloomberg];
                        
                        [temp_dic setObject:[dma objectForKey:DB_object_sqlite_basic_code_Google] forKey:DB_object_sqlite_basic_code_Google];
                        [temp_dic setObject:[dma objectForKey:DB_object_sqlite_basic_code_Yahoo] forKey:DB_object_sqlite_basic_code_Yahoo];
                        [temp_dic setObject:[dma objectForKey:DB_object_sqlite_basic_country] forKey:DB_object_sqlite_basic_country];
                        [temp_dic setObject:[dma objectForKey:DB_object_sqlite_basic_name_chinese] forKey:DB_object_sqlite_basic_name_chinese];
                        [temp_dic setObject:[dma objectForKey:DB_object_sqlite_basic_name_english] forKey:DB_object_sqlite_basic_name_english];
                        [temp_dic setObject:[dma objectForKey:DB_object_sqlite_basic_sample1] forKey:DB_object_sqlite_basic_sample1];
                        [temp_dic setObject:[dma objectForKey:DB_object_sqlite_basic_sample2] forKey:DB_object_sqlite_basic_sample2];
                        [temp_dic setObject:[dma objectForKey:DB_object_sqlite_basic_symbol] forKey:DB_object_sqlite_basic_symbol];
                        [temp_dic setObject:[dma objectForKey:DB_object_sqlite_basic_timezone] forKey:DB_object_sqlite_basic_timezone];
                                                
                    }
                    
                     [temp_table_object addObject:temp_dic];
                    
                     [temp_dic release];
                                           
                    // [temp_table_object addObject:dma];
                }
            }
            else{
                
            }
             [dic setObject:  temp_table_object     forKey:Node_Array_StockData];
            //[temp_table_object release];
        }
        //Node_Array_StockData_for_table
        [dic setObject:[[p tableobject] data_array_onlyfortableObject]  forKey:Node_Array_StockData_for_table];
        
        //[dic setObject:[[p tableobject] data_array_object_dic] forKey:Node_Array_StockData_dic];
                
        // [temp_table_object release];
        
        
        if([p hasChildren]==YES){
            // NSLog(@"有子"); 
            //進入子循環
            
            [dic setObject:  [self tree_convert_to_array:[p children]]  forKey:Node_children];    
            
        }
        else{
            //NSLog(@"沒有子");
            [dic setObject:@"" forKey:Node_children];  
        }
        
        [outputarrary addObject:dic];
        
        
    }
    //[outputarrary addObject:nil];
    //NSLog(@"outputarrary=%ld",[outputarrary count]);
    [outputarrary autorelease];
    return outputarrary;
    
}
//將陣列資料轉成要呈現的樹狀資料 
-(SourceListItem *)array_convert_to_tree:(NSArray * )importarrar paraobject:(SourceListItem *)paob{
    
    SourceListItem *chid=nil ; //注意只有回傳最後一個 並不是回傳全部SourceListItem
    
    for (NSDictionary *rd in importarrar ) {
        
        //標記:要增加點結構NODE的資料時，要增加的程式碼        
        chid = [SourceListItem itemWithTitle:[rd objectForKey:Node_title ] identifier:[rd objectForKey:Node_identifier ]];
        
        //設定資料模型參考位置給節點
        //[chid set_Data_model:self];        
        
        [chid setIcon: [rd objectForKey:Node_icon  ]];
        [chid setIsUseForGroup:[rd objectForKey:Node_isUseForGroup ]];
        [chid setBadgeValue:[NSString stringWithFormat:@"%d", [(NSNumber *)[rd objectForKey:Node_badgeValue ] intValue] ]];        
        
        //[[chid tableobject] setData_array_code:[rd objectForKey:Node_Array_StockData ] ];
        //請特別注意 此段會有記憶體遺漏 但是不可以處理掉 因為這裡是樹狀回圈 如果處理的話 就會當機        
        
        //1.Dataobject
        {
            NSMutableArray *temp_code_object_array=[[[NSMutableArray alloc] init] autorelease] ;
            
            //在下一層
            for (NSMutableDictionary *tab  in [rd objectForKey:Node_Array_StockData ]) {
                //主要是因ios 會把NSMutableDictionary *tab  視為不可變
                NSMutableDictionary *tableobject= [tab mutableCopy]  ;
               
                              
                //針對不同資料庫的調整主要代碼  
                if([datasource isEqualToString:id_Yahoo_WEB]){
                                     
                    
                    [tableobject setObject: [tableobject objectForKey:DB_object_sqlite_basic_code_Yahoo]     forKey:DB_object_sqlite_basic_code] ;  
                                   
                    
                } 
                
                else if([datasource isEqualToString:id_Yahoo_Mobile]){
                    [tableobject setObject:[tableobject objectForKey:DB_object_sqlite_basic_code_Yahoo] forKey:DB_object_sqlite_basic_code]; 
                }
                else if([datasource isEqualToString:id_MultiServer_GY]){
                    [tableobject setObject:[tableobject objectForKey:DB_object_sqlite_basic_code_Yahoo] forKey:DB_object_sqlite_basic_code];
                }
                
                else if([datasource isEqualToString:id_Google]){
                    [tableobject setObject:[tableobject objectForKey:DB_object_sqlite_basic_code_Google] forKey:DB_object_sqlite_basic_code]; 
                } 
                else if([datasource isEqualToString:id_Bloomberg]){
                    [tableobject setObject:[tableobject objectForKey:DB_object_sqlite_basic_code_Bloomberg] forKey:DB_object_sqlite_basic_code]; 
                } 
                
                //標記：如果未來新增某一欄位 需要檢查從檔案取出的array裡面有沒有缺某一個key Dataobject                
                          
                {
                    //如果未來有新增欄位就要在此做檢查並且新增
                    /*
                    if ([[tableobject allKeys] indexOfObject:DB_onlyfortableObject_positon_ProfitLoss_today]==NSNotFound) {
                        //加入新的 object 
                        [tableobject setObject:[NSNumber numberWithDouble:0] forKey:DB_onlyfortableObject_positon_ProfitLoss_today];
                        
                    }
                    else  if ([[tableobject allKeys] indexOfObject:DB_onlyfortableObject_positon_marketvalue]==NSNotFound) {
                        //加入新的 object 
                        [tableobject setObject:[NSNumber numberWithDouble:0] forKey:DB_onlyfortableObject_positon_marketvalue];
                        
                    }
                    else  if ([[tableobject allKeys] indexOfObject:DB_onlyfortableObject_positon_ProfitLoss_percent]==NSNotFound) {
                        //加入新的 object 
                        [tableobject setObject:[NSNumber numberWithDouble:0] forKey:DB_onlyfortableObject_positon_ProfitLoss_percent];
                        
                    }                    
                    else  if ([[tableobject allKeys] indexOfObject:DB_onlyfortableObject_positon_cost]==NSNotFound) {
                        //加入新的 object 
                        [tableobject setObject:[NSNumber numberWithDouble:0] forKey:DB_onlyfortableObject_positon_cost];
                        
                    } 
                     */
                    
                }                
                                
                [temp_code_object_array addObject:tableobject]; 
               [tableobject release];
                
            }
            
            
            /*
             在陣列結構轉換成樹狀結構時 檢查是不是此節點為資料夾或是觀察名單，如果
             是觀察名單就表示裡面有多檔股票資訊，並且將這些股票加入到資料模型並且與
             樹狀節點的觀察名單產生位置連結
             */
             
            if ([[chid isUseForGroup ]isEqualToNumber:[NSNumber numberWithBool:NO]]){  
                //不是資料夾
                [chid set_arraycode_to_data_array_object:  temp_code_object_array    set_Data_model:self];  
                //[ temp_code_array release]; 不可以加入此釋放
            }
            else{
                
                NSMutableArray *tempa;
                tempa=[[NSMutableArray alloc] init];
                [chid set_arraycode_to_data_array_object:tempa set_Data_model:self ];            
                [tempa release];
                
            }
        
        }
          
        
        
        //2.only_for_table
        {
            NSMutableArray *temp_code_for_table_array=[[[NSMutableArray alloc] init] autorelease] ;
            
            //在下一層
            for (NSMutableDictionary *tab  in [rd objectForKey:Node_Array_StockData_for_table ]) {
                NSMutableDictionary *tableobject= [tab mutableCopy]  ;                
                
                //針對不同資料庫的調整主要代碼  
                if([datasource isEqualToString:id_Yahoo_WEB]){
                    [tableobject setObject:[tableobject objectForKey:DB_object_sqlite_basic_code_Yahoo] forKey:DB_object_sqlite_basic_code];   
                    
                } 
                else if([datasource isEqualToString:id_Yahoo_Mobile]){
                    [tableobject setObject:[tableobject objectForKey:DB_object_sqlite_basic_code_Yahoo] forKey:DB_object_sqlite_basic_code]; 
                }
                else if([datasource isEqualToString:id_MultiServer_GY]){
                    [tableobject setObject:[tableobject objectForKey:DB_object_sqlite_basic_code_Yahoo] forKey:DB_object_sqlite_basic_code];
                }
                
                else if([datasource isEqualToString:id_Google]){
                    [tableobject setObject:[tableobject objectForKey:DB_object_sqlite_basic_code_Google] forKey:DB_object_sqlite_basic_code]; 
                } 
                else if([datasource isEqualToString:id_Bloomberg]){
                    [tableobject setObject:[tableobject objectForKey:DB_object_sqlite_basic_code_Bloomberg] forKey:DB_object_sqlite_basic_code]; 
                } 
                //標記：如果未來新增某一欄位 需要檢查從檔案取出的array裡面有沒有缺某一個key only_for_table                
                /*
                {
                    //如果未來有新增欄位就要在此做檢查並且新增                    
                    if ([[tableobject allKeys] indexOfObject:DB_onlyfortableObject_positon_ProfitLoss_today]==NSNotFound) {
                        //加入新的 object 
                        [tableobject setObject:[NSNumber numberWithDouble:0] forKey:DB_onlyfortableObject_positon_ProfitLoss_today];
                        
                    }
                    else  if ([[tableobject allKeys] indexOfObject:DB_onlyfortableObject_positon_cost]==NSNotFound) {
                        //加入新的 object 
                        [tableobject setObject:[NSNumber numberWithDouble:0] forKey:DB_onlyfortableObject_positon_cost];
                        
                    }                
                }
                */
                
                [temp_code_for_table_array addObject:tableobject]; 
                [tableobject release];
                
            }
            
            
            /*
             在陣列結構轉換成樹狀結構時 檢查是不是此節點為資料夾或是觀察名單，如果
             是觀察名單就表示裡面有多檔股票資訊，並且將這些股票加入到資料模型並且與
             樹狀節點的觀察名單產生位置連結
             */
            
            if ([[chid isUseForGroup ]isEqualToNumber:[NSNumber numberWithBool:NO]]){  
                //不是資料夾
                [[chid tableobject]  setData_array_onlyfortableObject:temp_code_for_table_array ];  
                //[ temp_code_array release]; 不可以加入此釋放
            }
            else{
                
                NSMutableArray *tempa;
                tempa=[[NSMutableArray alloc] init];
                [[chid tableobject]  setData_array_onlyfortableObject:temp_code_for_table_array ];           
                [tempa release];
                
            }
            
        }        
        
         
        //[temp_code_array autorelease];//不可以加入此釋放        
        
        
        //標記：樹狀結構的各個資料統計        
        [chid update_TableCalcuate:tree_sort_data];      
        
        
        //標記：重新調整報價表的名稱與物件順序 開始載入資料時
        //[chid reset_Table_code_data_array];
        
        
        [paob addChid:chid];
        [chid setParaent:paob];
        
        
        if ([ [rd objectForKey:Node_children ] isEqual:@""]   ) {
            // NSLog(@"沒有子陣列");
        }
        else{
            // NSLog(@"有子陣列--------------------下");
            //循環關鍵
            [self array_convert_to_tree:[rd objectForKey:Node_children] paraobject:chid ];
            
            
        }
        
        
    }
    
    return chid;
    
}
-(void)array_save_to_watchlist_plist:(SourceListItem*)tree write_path_filename:(NSString *)_w_path_name{
    
    
   
    
    //指定哪一個樹狀陣列要存檔
    SourceListItem *write_SLT;
    write_SLT=tree;     
    
    //將樹狀結構轉成存檔陣列 
    NSMutableArray *writearray;
    writearray= [self tree_convert_to_array: [write_SLT children]  ];
        
    
    //存檔
    [writearray writeToFile:_w_path_name atomically:YES];
     
   
    
}
-(void)save_all_tree_data:(SourceListItem *)_target_sourlist{
    
    //分辨最上層節點
    SourceListItem *sp= [_target_sourlist get_TopParaent];//選定的父節點
    NSLog(@"最上層節點的認證=%@",[sp identifier]);
    
    //針對不同的最上層來存檔
    if ([[sp identifier] isEqualToString:Node_System]) {
        
        //系統群組的存檔Para_SLT_system
        {
            //1.自選群組檔案路徑與名稱
            NSString *pathname;
            {
                NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
                
                NSString *Path_Para_SLT_watchlist_system  ;
                Path_Para_SLT_watchlist_system=[prefs objectForKey:Defaults_Path_Para_SLT_watchlist_system];
                
                NSString *filename=[NSString stringWithFormat: @"%@.plist",[File_Name_Path file_name_Watchlist_System]]  ;
                
                pathname=[Path_Para_SLT_watchlist_system stringByAppendingPathComponent:filename];
            }
            
            //2.存檔
            [self array_save_to_watchlist_plist:Para_SLT_system write_path_filename:pathname] ;
            
            
        }
        
    }
    else if ([[sp identifier] isEqualToString:Node_Custom]){
        //自設群組的存檔Para_SLT_watchlist
        {
            //1.自選群組檔案路徑與名稱
            NSString *pathname;
            {
                NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
                
                NSString *Path_Para_SLT_watchlist  ;
                Path_Para_SLT_watchlist=[prefs objectForKey:Defaults_Path_Para_SLT_watchlist];
                
                NSString *filename=[NSString stringWithFormat: @"%@.plist",[File_Name_Path file_name_Watchlist]]  ;
                
                pathname=[Path_Para_SLT_watchlist stringByAppendingPathComponent:filename];
            }
            
            //2.存檔
            [self array_save_to_watchlist_plist:Para_SLT_watchlist write_path_filename:pathname] ;
            
            
        }
    }      
    
     
}

#pragma mark -
#pragma mark 將某節點之下的所有節點 合集成一個陣列集合 含自己
-(void)node_sub_tree__to_array_loop:(NSMutableArray *)childarray{
//temp_all_sub_node
    //將子的tablecount更新
    for (SourceListItem *p in  childarray) {
        
        //將本身的bagedvalue 更新
        //標記：樹狀結構的各個資料統計        
        
        
        if([p hasChildren]==YES){
            
            //進入子循環
            [self  node_sub_tree__to_array_loop:[p children]];  
                       
            
            
            
        }
    
        
        [self.temp_all_sub_node addObject:p];        
    }      
    
    
}

-(void)node_sub_tree__to_array:(SourceListItem *)si{

    if ( temp_all_sub_node) {
        [ temp_all_sub_node release];
    }
    
     temp_all_sub_node=[[NSMutableArray alloc] init];
    
    //含有自己
    [ temp_all_sub_node addObject:si];
    
    //進入循環
    [self node_sub_tree__to_array_loop:[si children]];
    
}


#pragma mark -
#pragma mark 樹狀結構的統計計算
//統計樹狀資料的資料夾合計數目1
-(void)tree_folder_to_sum_array:(NSMutableArray *)childarray{
    
    //將子的tablecount更新
    for (SourceListItem *p in  childarray) {
        
        //將本身的bagedvalue 更新
        //標記：樹狀結構的各個資料統計        
       // 
        
        if([p hasChildren]==YES){
            
            //進入子循環
            [self  tree_folder_to_sum_array:[p children]];  
            
            /*範例
             //統計所有旗下的tablecount資料            
             {
             int sum;
             sum=0;
             
             for (SourceListItem *chsum in [p children] ) {
             if ([chsum badgeValue] <0) {
             sum=sum+0; 
             }
             else
             {
             sum=sum+[chsum badgeValue];                        
             }
             
             }
             
             [p setBadgeValue:sum];
             
             }
             */
            
            [p update_TableCalcuate:tree_sort_data];              
            
        }
        /*
        int tableibjectcount;
        tableibjectcount=[[[p tableobject] data_array_object] count];
        [p setBadgeValue:tableibjectcount];  
        */
        [p update_TableCalcuate:tree_sort_data];              
    }  
    
    
    
}
//統計樹狀資料的資料夾合計數目2
-(void)tree_folder_to_sum:(SourceListItem *)si{
    
    [self tree_folder_to_sum_array:[si children]];
    
}
//統計樹狀資料的資料夾合計數目3
-(void)update_all_tree_folder_to_sum{
    
    for (int i=0; i<[Para_SLT_Paraent_Array count]; i++) {
        
        
        [self tree_folder_to_sum: [Para_SLT_Paraent_Array objectAtIndex:i] ];        
        
    }    
    
    
}
#pragma mark -
#pragma mark 節點上的增加與刪減

//在選定的節點上增加資料夾
-(SourceListItem *)addFolder_on_select_tree_node:(SourceListItem *)select_node{
   
    //1.增加點結構NODE的資料時，要增加的程式碼
    SourceListItem *addlistFolder ;    
    {
        addlistFolder = [SourceListItem itemWithTitle:NSLocalizedString(@"Unnamed Folder", @"未命名 資料夾")  identifier:@"playlistgroup"];
        
        [addlistFolder setIcon:  @"Tree_Folder.png" ];        
        [addlistFolder setIsUseForGroup:[NSNumber numberWithBool:YES]];
        [addlistFolder set_arraycode_to_data_array_object :[[[NSMutableArray alloc] init] autorelease] set_Data_model:self];        
        
        SourceListItem *playlistGroupItem = [SourceListItem itemWithTitle:NSLocalizedString(@"Unnamed List", @"未命名 觀察名單") identifier:@"childplaylist"];
        [playlistGroupItem setIcon: @"Tree_Document.png" ];
        [playlistGroupItem setIsUseForGroup:[NSNumber numberWithBool:NO]];
        [playlistGroupItem set_arraycode_to_data_array_object: [[[NSMutableArray alloc] init] autorelease] set_Data_model:self];        
        
        
        //加入關係子                          
        [addlistFolder setIsUseForGroup:[NSNumber numberWithBool: YES]];
        [addlistFolder setChildren: [ [[NSMutableArray alloc]   initWithObjects:playlistGroupItem,nil] autorelease] ];
        
        //加入關係母                        
        [playlistGroupItem setParaent:addlistFolder];          
        
        [[select_node paraent] addChid:addlistFolder];
        [addlistFolder setParaent:[select_node paraent]];   
    }
    
    //2.增加節點後 要進行的整理動作
    {
        //1.將子節點上的個股匯整到上一層的節點
        [self tree_form_top_to_sub_node:select_node];
        
        //2.更新計算每個節點上要計算的東西
        //[self  update_all_tree_folder_to_sum];
        
        //3.儲存所有樹狀資料
        [self save_all_tree_data:select_node];
    }
   
    //3.回傳增加的節點
    return  addlistFolder;
}

//在選定的節點的下一個階層增加資料夾
-(SourceListItem *)addFolder_on_select_tree_node_sub:(SourceListItem *)select_node{
    
    //1.增加點結構NODE的資料時，要增加的程式碼
    SourceListItem *addlistFolder_sub ;    
    {
        //標記:要增加點結構NODE的資料時，要增加的程式碼
        addlistFolder_sub= [SourceListItem itemWithTitle:NSLocalizedString(@"Unnamed Folder", @"未命名 資料夾") identifier:@"playlistgroup"];
        [addlistFolder_sub setIcon: @"Tree_Folder.png" ];        
        [addlistFolder_sub setIsUseForGroup:[NSNumber numberWithBool:YES]];
        [addlistFolder_sub set_arraycode_to_data_array_object: [[[NSMutableArray alloc] init] autorelease] set_Data_model:self];          
        
        
        SourceListItem *playlistGroupItem = [SourceListItem itemWithTitle:NSLocalizedString(@"Unnamed List", @"未命名 觀察名單")  identifier:@"childplaylist"];
               
        [playlistGroupItem setIcon: @"Tree_Document.png" ];
        [playlistGroupItem setIsUseForGroup:[NSNumber numberWithBool:NO]];
        [playlistGroupItem set_arraycode_to_data_array_object: [[[NSMutableArray alloc] init] autorelease] set_Data_model:self];          
        
        //加入關係子                          
        [addlistFolder_sub setIsUseForGroup:[NSNumber numberWithBool: YES]];
        [addlistFolder_sub setChildren: [[[NSMutableArray alloc] initWithObjects:playlistGroupItem,nil]  autorelease]];
        //加入關係母                        
        [playlistGroupItem setParaent:addlistFolder_sub];          
        
        [select_node  addChid:addlistFolder_sub];
        [addlistFolder_sub setParaent: select_node  ];      
    }
    
    //2.增加節點後 要進行的整理動作
    {
        //1.將子節點上的個股匯整到上一層的節點
         [self tree_form_top_to_sub_node:select_node];
        
        //2.更新計算每個節點上要計算的東西
         //[self  update_all_tree_folder_to_sum];
        
        //3.儲存所有樹狀資料
        [self save_all_tree_data:select_node];
    }
       
    //3.回傳增加的節點
    return addlistFolder_sub;
    
}

//在選定的節點上增加自選股組合
-(SourceListItem *)addwatchlist_on_select_tree_node:(SourceListItem *)select_node{
    NSLog(@"select b=%@",[select_node identifier]);
    
    //1.增加點結構NODE的資料時，要增加的程式碼 
    SourceListItem *playlistGroupItem ;    
    {
    
        playlistGroupItem = [SourceListItem itemWithTitle:NSLocalizedString(@"Unnamed List", @"未命名 觀察名單")  identifier:@"childplaylist"];        
       
        //設定資料模型給節點
        //[playlistGroupItem set_Data_model:datamodel];          
        [playlistGroupItem setIcon: @"Tree_Document.png"] ;
        [playlistGroupItem setIsUseForGroup:[NSNumber numberWithBool:NO]];         
        
        
        [playlistGroupItem set_arraycode_to_data_array_object:[ [[NSMutableArray alloc] init] autorelease] set_Data_model:self]; 
        
        //加入關係母                        
        [playlistGroupItem setParaent:[select_node paraent]];          
        [[select_node paraent] addChid:playlistGroupItem];    
    }
   
    //2.增加節點後 要進行的整理動作
    {
        //1.將子節點上的個股匯整到上一層的節點
        [self tree_form_top_to_sub_node:select_node];
        
        //2.更新計算每個節點上要計算的東西
        //[self  update_all_tree_folder_to_sum];
        
        //3.儲存所有樹狀資料
        [self save_all_tree_data:select_node];
    }    
    
    //3.回傳增加的節點
    return playlistGroupItem;
}

//在選定的節點下一個階層增加自選股組合
-(SourceListItem *)addwatchlist_on_select_tree_node_sub:(SourceListItem *)select_node{
   
    //1.增加點結構NODE的資料時，要增加的程式碼 
    SourceListItem *playlistGroupItem ;
    {
        playlistGroupItem= [SourceListItem itemWithTitle:NSLocalizedString(@"Unnamed List", @"未命名 觀察名單")  identifier:@"childplaylist"];
        //[playlistGroupItem set_Data_model:datamodel];        
        [playlistGroupItem setIcon: @"Tree_Document.png" ];
        [playlistGroupItem setIsUseForGroup:[NSNumber numberWithBool:NO]];         
        [playlistGroupItem set_arraycode_to_data_array_object:[ [[NSMutableArray alloc] init] autorelease] set_Data_model:self];
        
        
        //加入關係母                        
        [playlistGroupItem setParaent: select_node ];          
        [select_node  addChid:playlistGroupItem];  
        
     
    
    }
      
    //2.增加節點後 要進行的整理動作
    {
        //1.將子節點上的個股匯整到上一層的節點
        [self tree_form_top_to_sub_node:select_node];
        
        //2.更新計算每個節點上要計算的東西
        //[self  update_all_tree_folder_to_sum];
        
        //3.儲存所有樹狀資料
        [self save_all_tree_data:select_node];
    }    
    
    //3.回傳增加的節點    
    return playlistGroupItem;

}

#pragma mark -
#pragma mark 節點上的拷貝
-(SourceListItem *)copyFolder_on_select_tree_node:(SourceListItem *)select_node{
    
    
    //標記:要增加點結構NODE的資料時，要增加的程式碼
    SourceListItem *playlistGroupItem     ;
     
    //方法一：採用深度拷貝的方式：很重要的技巧：深度拷貝 就是利用壓縮的方式重新完全複製節點 會很慢 無辦法解決
    {
        //NSData*data=[NSKeyedArchiver archivedDataWithRootObject:select_node];
        //playlistGroupItem=[NSKeyedUnarchiver unarchiveObjectWithData:data];
    
        //加入關係母
        //[playlistGroupItem setParaent:[select_node paraent]];
        //[[select_node paraent] addChid:playlistGroupItem];
    
    }
    //方法二：先轉換成為陣列->儲存陣列->取出陣列->轉成SourceListItem
    {
        //轉成陣列
        NSArray *sourlist_array=[NSArray arrayWithObjects:select_node, nil];
        NSMutableArray *array_from_tree=[self tree_convert_to_array:sourlist_array];
    
        //取出陣列 存放在硬碟內
        NSMutableArray *read_array;
        {
            //歷史檔案路徑
            NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
            NSString *Path_Para_SLT_watchlist  ;
            Path_Para_SLT_watchlist=[prefs objectForKey:Defaults_Path_Para_SLT_watchlist];
            
            //儲存
            [array_from_tree writeToFile:[Path_Para_SLT_watchlist stringByAppendingPathComponent:@"temp.plist"] atomically:YES];
            
            //取出
            read_array=[NSArray arrayWithContentsOfFile:[Path_Para_SLT_watchlist stringByAppendingPathComponent:@"temp.plist"]];
            
            
        }
        
        //將該陣列轉換成要複製的SourceListItem
        playlistGroupItem= [self array_convert_to_tree:read_array paraobject:[select_node paraent]];
        
    }
    
    
  
    
    
       
    //2.增加節點後 要進行的整理動作
    {
                
        //1.將子節點上的個股匯整到上一層的節點
        //從會上層的節點往下整理
        [self tree_form_top_to_sub_node:playlistGroupItem];
        
        
        //2.更新計算每個節點上要計算的東西
         [self  update_all_tree_folder_to_sum];
         
        //3.儲存所有樹狀資料
        [self save_all_tree_data:select_node];
         
    }    

    
    return [playlistGroupItem retain];
}

#pragma mark -
#pragma mark 節點上的 更名 刪除
-(void)Rename_SourceListItem:(SourceListItem *)selectnode newName:(NSString *)newname{

    if ([newname retainCount]>0) {
        [selectnode setTitle:newname];
        [self save_all_tree_data:selectnode];
    }
    
    [self tree_form_top_to_sub_node:selectnode];
   // [self update_all_tree_folder_tableobject_refresh:1];

}
//刪除單一
-(void)delete_singal_SourceListItem:(SourceListItem *)selectnode{
   
    //先存放，等一下就要馬上移除selectnode
    SourceListItem *select_node_parent=[selectnode paraent];
    
    //移除選定的節點
    NSLog(@"移除選定的節點");
    
    [[[selectnode paraent] children] removeObject:selectnode];
    
    //2.增加節點後 要進行的整理動作
    {
        //1.將子節點上的個股匯整到上一層的節點
        //從會上層的節點往下整理
        [self tree_form_top_to_sub_node:select_node_parent];
        
        //2.更新計算每個節點上要計算的東西
        [self  update_all_tree_folder_to_sum];
        
        //3.儲存所有樹狀資料
        [self save_all_tree_data:selectnode];
    } 
    

}
 
#pragma mark -
#pragma mark 節點上的tableobject重新整理

//針對表格上所有股票與欄位進行計算
-(void)table_column_caluate_all:(PXTableObject *)tablee{
    
    for (NSMutableDictionary *tc in  [table_column_object_array table_column_array] ) {  
  
        //找出所有欄位資料之後 看此欄位是否需要在報價結束後要進行計算動作
        if ([[tc objectForKey:Table_Column_iscalcuate_After_Quoted_Finished] isEqualToNumber:[NSNumber numberWithBool:YES]]) {
             
            [tablee calculate_table_byarray_all:[tc objectForKey:Table_Column_Key]];            
            
        } 
        
        
    }         
}

//輸入孫或子任一層的節點之後 反推到最頂層的節點,從該最上層的節點往下更新節點資料結構
-(void)tree_form_top_to_sub_node:(SourceListItem *)any_para_SLI{
   
    //1.先建立一個存放的記憶體
    NSMutableArray *all_node=[[[NSMutableArray alloc] init] autorelease];
    
    //2.找到要向上搜尋的結點
    [any_para_SLI get_ALLParaent:all_node];
    
    //3.取出所有節點位置資料
    for (SourceListItem *upnode in all_node  ) {
        NSLog(@"popUpAction=%@",  [upnode title ] );
    }
    
    //4.從最上層更新下來
    if ([all_node count]>0) {
        SourceListItem *tops=[all_node objectAtIndex:[all_node count]-1];
        [self tree_folder_tableobject_single_sourlist:tops];
    }
    
    
    
}


//輸入SourceListItem 節點本身 自我循環-內
-(void)tree_folder_tableobject_single_sourlist:(SourceListItem *)para_SLI{
    
    //將本身的bagedvalue 更新
    //標記：樹狀結構的各個資料統計
    if([para_SLI hasChildren]==YES){
        
        
        //1.進入子 自我循環 
        [self  tree_folder_tableobject_single_array:[para_SLI children]];         
        
        //======此段就是用來加入每個循環節點要做的事情
        {
            //2.先清空本身的資料 !!!!很重要
            [[[para_SLI tableobject] data_array_object] removeAllObjects];
            [[[para_SLI tableobject] data_array_node] removeAllObjects];
            [[[para_SLI tableobject] data_array_onlyfortableObject] removeAllObjects];
            
            //3.開始將下層的節點個股結果加入到此層表上
            //只有目前的節點是資料夾屬性 才需要此動作
            if ([[para_SLI isUseForGroup ]isEqualToNumber:[NSNumber numberWithBool:YES]]){
              
                //a.主要是重新放入所有子節點下的Data_Object 至 data_array_object
                for (SourceListItem *child_SLI in [para_SLI children] ) {
                    
                    //資料存放在 data_array_object
                    for (Data_Object *child_do in [[child_SLI tableobject] data_array_object]) {
                        
                        
                        //從每個下一層的表格代碼取出比對目前這一層的tableobject 裡有沒有此資料
                        
                        //取出子表格上的資料物件的代碼
                        NSString *code_intable;
                        code_intable=[[child_do table_data] objectForKey:DB_object_sqlite_basic_code] ;
                        
                        //檢視目前該股票在para_SLI 的位置
                        NSUInteger  idxx;
                        idxx=  [[para_SLI tableobject] index_data_arrary_object_from_code:code_intable]  ;
                        
                        //母節點上的data_array_object 無此資料所以添加上去
                        if (idxx==NSNotFound){
                            //加入 data_array_object                             
                            [[[para_SLI tableobject ] data_array_object] addObject:child_do ];
                            
                            
                        }
                        
                        
                    }
                    
                }
                
                //b.針對子表格上所有股票與 需要計算的欄位進行計算（例如損益欄位） 子=>表格水平值的計算
                {
                    //有效率的算法
                    for (NSMutableDictionary *tc in  [table_column_object_array table_column_array] ) {
                        
                        //找出所有欄位資料之後 看此欄位是否需要在報價結束後要進行計算動作
                        if ([[tc objectForKey:Table_Column_iscalcuate_After_Quoted_Finished] isEqualToNumber:[NSNumber numberWithBool:YES]]) {
                            
                            for (SourceListItem *child_SLI in [para_SLI children] ) {
                                
                                [[child_SLI tableobject] calculate_table_byarray_all:[tc objectForKey:Table_Column_Key]];
                            }
                            
                        }
                    }
                    
                    //無效率的算法
                    /*
                     for (SourceListItem *child_SLI in [para_SLI children] ) {
                     
                     
                     [self table_column_caluate_all:[child_SLI tableobject]];
                     
                     
                     }
                     */                }
                
                //c.將子表格的資料彙整合計到母表格上
                for (SourceListItem *child_SLI in [para_SLI children] ) {
                    
                    //資料存放在 data_array_onlyfortableObject =>針對表格上的特定資料 (部位資料數據的加總)
                    for (Data_Object *child_do in [[child_SLI tableobject] data_array_object]) {                         
                       
                        //檢查物件陣列裡的代碼是否相同作為基準
                        NSString *code_intable;
                        code_intable=[[child_do table_data] objectForKey:DB_object_sqlite_basic_code] ;
                        
                        
                        //取出子物件表格上特有字典資料
                        NSMutableDictionary *child_onlyfortableObject = [[child_SLI tableobject] object_data_arrary_only_for_table_from_code:code_intable];
                        
                        NSUInteger  indxx_child;//子表格位置
                        indxx_child=[[child_SLI tableobject] index_data_arrary_only_for_table_from_code: code_intable];
                        
                        if (!(indxx_child ==NSNotFound)) {
                        //表示子表格有該字典資料
                            
                            NSUInteger  idxx;//母表格位置
                            idxx=  [[para_SLI tableobject] index_data_arrary_only_for_table_from_code:code_intable ]  ;
                            
                            
                            if (idxx==NSNotFound) {
                                //母表格目前無該字典資料
                               
                                //第一次
                                //加入個別資料物件
                                {
                                    //因為是每個表格的資料都是獨立 所以需要此方法複製資料
                                    NSMutableDictionary *copy_d;
                                    NSData*data=[NSKeyedArchiver archivedDataWithRootObject:child_onlyfortableObject];
                                    copy_d=[NSKeyedUnarchiver unarchiveObjectWithData:data];
                                    
                                    [[[para_SLI tableobject ] data_array_onlyfortableObject] addObject:copy_d ];
                                }
                                
                                
                            }
                            else {
                                
                                //表示兩個子節點有相同的股票名稱 或是說母節點表格上已經有該資料
                                
                                
                                //標記：部位-數據是依據其他欄位資料計算出來 5.重新計算母節點數據
                                //標記：部位-自行輸入資料(此數據會啟動其他欄位被計算) 5.重新計算母節點數據
                                
                                NSMutableDictionary *para_dic;
                                para_dic= [[para_SLI tableobject] object_data_arrary_only_for_table_from_code:[ child_onlyfortableObject  objectForKey:DB_object_sqlite_basic_code] ]  ;
                                
                                //1:母 數據 0:子 數據
                                //數量
                                int  position_count_0;
                                position_count_0= [[child_onlyfortableObject objectForKey:DB_onlyfortableObject_positon_count] intValue]  ;
                                
                                int  position_count_1; //
                                position_count_1= [[para_dic objectForKey:DB_onlyfortableObject_positon_count] intValue]  ;
                                //進場價格
                                double enter_price_0;
                                enter_price_0= [[child_onlyfortableObject objectForKey:DB_onlyfortableObject_positon_EnterPrice] doubleValue]  ;
                                
                                double enter_price_1;
                                enter_price_1= [[para_dic objectForKey:DB_onlyfortableObject_positon_EnterPrice] doubleValue]  ;
                                
                                //市值專用
                                double marketvalue_0;
                                marketvalue_0= [[child_onlyfortableObject objectForKey:DB_onlyfortableObject_positon_marketvalue] doubleValue]  ;
                                
                                double marketvalue_1;
                                marketvalue_1= [[para_dic objectForKey:DB_onlyfortableObject_positon_marketvalue] doubleValue]  ;
                                
                                //累計報酬率
                                double profit_percent_0;
                                profit_percent_0= [[child_onlyfortableObject objectForKey:DB_onlyfortableObject_positon_ProfitLoss_percent] doubleValue]  ;
                                
                                double profit_percent_1;
                                profit_percent_1= [[para_dic objectForKey:DB_onlyfortableObject_positon_ProfitLoss_percent] doubleValue]  ;
                                
                                //成本
                                double cost_0;
                                cost_0= [[child_onlyfortableObject objectForKey:DB_onlyfortableObject_positon_cost] doubleValue]  ;
                                
                                double cost_1;
                                cost_1= [[para_dic objectForKey:DB_onlyfortableObject_positon_cost] doubleValue]  ;
                                
                                //範例 主動變數
                                double entersample_0;
                                entersample_0= [[child_onlyfortableObject objectForKey:DB_onlyfortableObject_positon_EnterSample] doubleValue]  ;
                                
                                double entersample_1;
                                entersample_1= [[para_dic objectForKey:DB_onlyfortableObject_positon_EnterSample] doubleValue]  ;
                                
                                //範例 被動變數
                                double bbentersample_0;
                                bbentersample_0= [[child_onlyfortableObject objectForKey:DB_onlyfortableObject_positon_valueChangeSample] doubleValue]  ;
                                
                                double bbentersample_1;
                                bbentersample_1= [[para_dic objectForKey:DB_onlyfortableObject_positon_valueChangeSample] doubleValue]  ;
                                
                                
                                //範例 主動變數
                                double entersample1_0;
                                entersample1_0= [[child_onlyfortableObject objectForKey:DB_onlyfortableObject_positon_EnterSample1] doubleValue]  ;
                                
                                double entersample1_1;
                                entersample1_1= [[para_dic objectForKey:DB_onlyfortableObject_positon_EnterSample1] doubleValue]  ;
                                
                                //範例 被動變數
                                double bbentersample1_0;
                                bbentersample1_0= [[child_onlyfortableObject objectForKey:DB_onlyfortableObject_positon_valueChangeSample1] doubleValue]  ;
                                
                                double bbentersample1_1;
                                bbentersample1_1= [[para_dic objectForKey:DB_onlyfortableObject_positon_valueChangeSample1] doubleValue]  ;
                                
                                
                                //進行資料合計之後的替換
                                {
                                    //範例 主動變數
                                    {
                                        [para_dic removeObjectForKey:DB_onlyfortableObject_positon_EnterSample];
                                        [para_dic setObject:[NSNumber numberWithDouble:(entersample_1+entersample_0   )] forKey:DB_onlyfortableObject_positon_EnterSample];
                                    }
                                    //範例 被動變數
                                    {
                                        [para_dic removeObjectForKey:DB_onlyfortableObject_positon_valueChangeSample];
                                        [para_dic setObject:[NSNumber numberWithDouble:(bbentersample_1+bbentersample_0   )] forKey:DB_onlyfortableObject_positon_valueChangeSample];
                                    }
                                    
                                    //範例1 主動變數
                                    {
                                        [para_dic removeObjectForKey:DB_onlyfortableObject_positon_EnterSample1];
                                        [para_dic setObject:[NSNumber numberWithDouble:(entersample1_1+entersample1_0   )] forKey:DB_onlyfortableObject_positon_EnterSample1];
                                    }
                                    //範例1 被動變數
                                    {
                                        [para_dic removeObjectForKey:DB_onlyfortableObject_positon_valueChangeSample1];
                                        [para_dic setObject:[NSNumber numberWithDouble:(bbentersample1_1+bbentersample1_0   )] forKey:DB_onlyfortableObject_positon_valueChangeSample1];
                                    }
                                    
                                    
                                    //部位數量
                                    {
                                        
                                        [para_dic removeObjectForKey:DB_onlyfortableObject_positon_count];
                                        [para_dic setObject:[NSNumber numberWithDouble:(position_count_0+position_count_1   )] forKey:DB_onlyfortableObject_positon_count];
                                    }
                                    //進場價位
                                    {
                                        //重新計算平均成本
                                        double average_enter_price;
                                        
                                        if (position_count_0+position_count_1 ==0) {
                                            average_enter_price=0;
                                        }
                                        else {
                                            average_enter_price=(enter_price_0*position_count_0+enter_price_1*position_count_1)/(position_count_0+position_count_1 );
                                        }
                                        
                                        [para_dic removeObjectForKey:DB_onlyfortableObject_positon_EnterPrice];
                                        
                                        [para_dic setObject:[NSNumber numberWithDouble: average_enter_price] forKey:DB_onlyfortableObject_positon_EnterPrice];
                                        
                                    }
                                    
                                    //市值
                                    {
                                        
                                        [para_dic removeObjectForKey:DB_onlyfortableObject_positon_marketvalue];
                                        [para_dic setObject:[NSNumber numberWithDouble:(marketvalue_0 +marketvalue_1   )] forKey:DB_onlyfortableObject_positon_marketvalue];
                                    }
                                    //累計報酬率
                                    {
                                        
                                        [para_dic removeObjectForKey:DB_onlyfortableObject_positon_ProfitLoss_percent];
                                        [para_dic setObject:[NSNumber numberWithDouble:(profit_percent_0 +profit_percent_1   )] forKey:DB_onlyfortableObject_positon_ProfitLoss_percent];
                                    }
                                    //成本
                                    {
                                        
                                        [para_dic removeObjectForKey:DB_onlyfortableObject_positon_cost];
                                        [para_dic setObject:[NSNumber numberWithDouble:(cost_0 +cost_1   )] forKey:DB_onlyfortableObject_positon_cost];
                                    }
                                }
                                
                                
                                
                                //累計損益不計算是因為是採用另外一種表格計算方法
                                
                                
                            }
                            
                            
                        }
                        
                        
                        
                        
                    }
                    
                    
                }
                
                //d.資料存放在 data_array_node =>屬於通用的資料 (節點名稱與重復次數)
                for (SourceListItem *child_SLI in [para_SLI children] ) {
                                       
                   
                    for (Data_Object *child_do in [[child_SLI tableobject] data_array_object]) {
                        
                        //從每個下一層的表格代碼取出比對目前這一層的tableobject 裡有沒有此資料
                        
                        //取出子表格上的資料物件的代碼
                        NSString *code_intable;
                        code_intable=[[child_do table_data] objectForKey:DB_object_sqlite_basic_code] ;
                        
                        
                        //取出子物件資料 部位資料
                        NSMutableDictionary *child_onlyfortableObject = [[child_SLI tableobject] object_data_arrary_only_for_table_from_code:code_intable];
                        
                        NSUInteger  idxx_childx;
                        idxx_childx = [[child_SLI tableobject]  index_data_arrary_only_for_table_from_code: code_intable];
                        
                        NSUInteger  idxx;
                        idxx=  [[para_SLI tableobject] index_data_arrary_node_from_code: code_intable]  ;
                        
                        if (!(idxx_childx==NSNotFound))  {
                            
                            if (idxx==NSNotFound)
                            {
                                //加入 data_array_node
                                
                                NSMutableDictionary *dic;
                                dic=[[NSMutableDictionary alloc] init];
                                
                                //標記：節點-上加入從下一層萃取出來的整合資料 4.實作方法 初始資料
                                
                                //1.代碼
                                [dic setObject: [[child_do table_data] objectForKey:DB_object_sqlite_basic_code] forKey:DB_object_sqlite_basic_code];
                                
                                //2.節點名稱
                                [dic setObject: [(SourceListItem *)child_SLI title] forKey:DB_node_name_repeat];
                                
                                //3.節點名稱重復次數
                                [dic setObject: [NSNumber numberWithInt:1] forKey:DB_node_name_repeat_count];
                                
                                
                                //4.加入子物件的部位陣列物件
                                {
                                    NSMutableArray *temp=[[NSMutableArray alloc] init];
                                    
                                    [child_onlyfortableObject removeObjectForKey:DB_node_name_repeat];
                                    [child_onlyfortableObject setObject:[(SourceListItem *)child_SLI title] forKey:DB_node_name_repeat];
                                    [temp addObject:child_onlyfortableObject];
                                    
                                    [dic setObject: temp forKey:DB_node_child_node__onlyfortableObject_positon];
                                    [temp release];
                                }
                                
                                
                                //5.將子物件的節點名稱與部位數量資料取出來設定
                                {
                                    NSMutableArray *node_child_position_array=[dic objectForKey:DB_node_child_node__onlyfortableObject_positon];
                                    
                                    //DB_node_position_count 部位數量
                                    {
                                        NSString *p_count;
                                        p_count=@"";
                                        for (NSMutableDictionary *dd in node_child_position_array) {
                                            if ([p_count isEqualToString:@""]) {
                                                p_count=[NSString stringWithFormat:@"(%@ %i)" ,[dd objectForKey:DB_node_name_repeat],[[dd objectForKey:DB_onlyfortableObject_positon_count] intValue]];
                                                
                                            }
                                            else {
                                                p_count=[NSString stringWithFormat:@"%@,(%@ %i)",p_count,[dd objectForKey:DB_node_name_repeat],[[dd objectForKey:DB_onlyfortableObject_positon_count] intValue]];
                                                
                                                
                                            }
                                            
                                        }
                                        [dic setObject: p_count forKey:DB_node_position_count];
                                    }
                                    //DB_node_position_ProfitLoss_percent 報酬率
                                    {
                                        NSString *p_count;
                                        p_count=@"";
                                        for (NSMutableDictionary *dd in node_child_position_array) {
                                            if ([p_count isEqualToString:@""]) {
                                                p_count=[NSString stringWithFormat:@"(%@ %.2f%%)" ,[dd objectForKey:DB_node_name_repeat],[[dd objectForKey:DB_onlyfortableObject_positon_ProfitLoss_percent] floatValue]];
                                                
                                            }
                                            else {
                                                p_count=[NSString stringWithFormat:@"%@,(%@ %.2f%%)",p_count,[dd objectForKey:DB_node_name_repeat],[[dd objectForKey:DB_onlyfortableObject_positon_ProfitLoss_percent] floatValue]];
                                                
                                                
                                            }
                                            
                                        }
                                        [dic setObject: p_count forKey:DB_node_position_ProfitLoss_percent];
                                    }
                                    
                                }
                                
                                //6.樣本範例
                                [dic setObject: @"節點樣本範例" forKey:DB_node_name_repeat_addsample];
                                
                                
                                [[[para_SLI tableobject ] data_array_node] addObject:dic ];
                                [dic release];
                                
                            }
                            else {
                                //重複 所以需要修改存放的節點資料data_array_node
                                {
                                    
                                    
                                    //取出字典資料參考位置
                                    NSMutableDictionary *node_dic;
                                    node_dic=[[para_SLI tableobject ] object_data_arrary_node_from_code: [[child_do table_data] objectForKey:DB_object_sqlite_basic_code]];
                                    
                                    
                                    //1.更新計算新的節點整合資料
                                    NSString *node_name;
                                    int count;
                                    NSString *addsample;
                                    NSString *node_position_count;
                                    NSString *node_position_ProfitLoss_percent;
                                    
                                    
                                    NSMutableArray *node_position; //節點部位陣列 存放所有子的部位字典資料
                                    {
                                        //標記：節點-上加入從下一層萃取出來的整合資料 4.實作方法 更新資料-取出資料及改變資料
                                        //1.取出原來存放的節點名稱
                                        node_name=[node_dic objectForKey:DB_node_name_repeat];
                                        //2.節點名稱在加入新的節點名稱
                                        node_name=[node_name stringByAppendingFormat:@",%@",[(SourceListItem *)child_SLI title]];
                                        //3.節點重復次數+1
                                        count=[[node_dic objectForKey:DB_node_name_repeat_count] intValue]+1;
                                        
                                        //4.取出結點部位陣列
                                        {
                                            //取出所有子陣列
                                            node_position=[[node_dic objectForKey:DB_node_child_node__onlyfortableObject_positon] retain];
                                            
                                            //加入子節點名稱
                                            [child_onlyfortableObject removeObjectForKey:DB_node_name_repeat];
                                            [child_onlyfortableObject setObject:[(SourceListItem *)child_SLI title] forKey:DB_node_name_repeat];
                                            
                                            [node_position addObject:child_onlyfortableObject];
                                        }
                                        
                                        //5.次節點部位數據更新
                                        {
                                            //DB_node_position_count 部位數量
                                            NSString *p_count;
                                            {
                                                p_count=@"";
                                                for (NSMutableDictionary *dd in node_position) {
                                                    if ([p_count isEqualToString:@""]) {
                                                        p_count=[NSString stringWithFormat:@"(%@ %i)" ,[dd objectForKey:DB_node_name_repeat],[[dd objectForKey:DB_onlyfortableObject_positon_count] intValue]];
                                                        
                                                    }
                                                    else {
                                                        p_count=[NSString stringWithFormat:@"%@,(%@ %i)",p_count,[dd objectForKey:DB_node_name_repeat],[[dd objectForKey:DB_onlyfortableObject_positon_count] intValue]];
                                                        
                                                        
                                                    }
                                                    
                                                }
                                            }
                                            node_position_count=p_count;
                                            
                                            //DB_node_position_ProfitLoss_percent 部位報酬率
                                            //NSString *p_ProfitLoss_percent;
                                            NSString *p_profitpercent;
                                            {
                                                p_profitpercent=@"";
                                                for (NSMutableDictionary *dd in node_position) {
                                                    if ([p_profitpercent isEqualToString:@""]) {
                                                        p_profitpercent=[NSString stringWithFormat:@"(%@ %.2f%%)" ,[dd objectForKey:DB_node_name_repeat],[[dd objectForKey:DB_onlyfortableObject_positon_ProfitLoss_percent] floatValue]];
                                                        
                                                    }
                                                    else {
                                                        p_profitpercent=[NSString stringWithFormat:@"%@,(%@ %.2f%%)",p_profitpercent,[dd objectForKey:DB_node_name_repeat],[[dd objectForKey:DB_onlyfortableObject_positon_ProfitLoss_percent] floatValue]];
                                                        
                                                        
                                                    }
                                                    
                                                }
                                            }
                                            node_position_ProfitLoss_percent=p_profitpercent;
                                            
                                            
                                            
                                        }
                                        
                                        //6.樣本範例
                                        addsample=@"節點樣本範例";
                                    }
                                    
                                    //2.移除原本字典上所有的資料
                                    [node_dic removeAllObjects];
                                    
                                    //3.換上新的資料
                                    {
                                        
                                        //標記：節點-上加入從下一層萃取出來的整合資料 4.實作方法 更新資料-設定資料
                                        [node_dic setObject: node_name forKey:DB_node_name_repeat];
                                        
                                        [node_dic setObject: [NSNumber numberWithInt:count] forKey:DB_node_name_repeat_count];
                                        
                                        [node_dic setObject: [[child_do table_data] objectForKey:DB_object_sqlite_basic_code] forKey:DB_object_sqlite_basic_code];
                                        
                                        [node_dic setObject:node_position_count forKey:DB_node_position_count];
                                        
                                        [node_dic setObject:node_position_ProfitLoss_percent forKey:DB_node_position_ProfitLoss_percent];
                                        
                                        [node_dic setObject:addsample forKey:DB_node_name_repeat_addsample];
                                        
                                        [node_dic setObject:node_position forKey:DB_node_child_node__onlyfortableObject_positon];
                                        
                                        
                                        [node_position release]; //記住要release
                                        
                                        
                                    }
                                    
                                    
                                }
                                
                                
                                
                            }
                            
                            
                        }
                        
                        
                    }                     
                    
                }
            }
                                   
                        
            //針對data_array_object 排序 因為此節點的順序已經重組過需要再次回復到上次的排序標頭
            [[para_SLI tableobject] sort_data_array_object_table_column_object_array:table_column_object_array identfiler_table_column:@"" sort_direction:@"" isSort_Node_para:YES];
            
        }
        
        
        
        //==========================================
    }
    else{
        
        //沒有子節點
        if ( [[para_SLI isUseForGroup] isEqualToNumber:[NSNumber numberWithBool:YES]]) {
            
            //表示 該para_SLI 是 空白資料夾
            
            //很重要的清除工作
            if ([[para_SLI tableobject] data_array_object]) {
                [[[para_SLI tableobject] data_array_object] removeAllObjects];
            }
            
            if ([[para_SLI tableobject] data_array_node]) {
                [[[para_SLI tableobject] data_array_node] removeAllObjects];
            }
            
            if ([[para_SLI tableobject] data_array_onlyfortableObject]) {
                [[[para_SLI tableobject] data_array_onlyfortableObject] removeAllObjects];
            }
            
            
            
            
        }
        
        
    }
}

//輸入SourceListItem 節點的子陣列節點 自我循環-外
-(void)tree_folder_tableobject_single_array:(NSMutableArray *)childarray{
    
    //將子的tablecount更新
    
    for (SourceListItem *para_SLI in  childarray) {
        
        [self tree_folder_tableobject_single_sourlist:para_SLI];
        
    }
    
}

//tableobject重新整理2
-(void)tree_folder_tableobject_refresh:(SourceListItem *)si{
   
    NSLog(@"tableobject重新整理2=%@",[si title]);
    
   
    [self tree_folder_tableobject_single_array:[si children]];
   
    
    //針對表格上所有股票與欄位進行計算 母
    [self table_column_caluate_all:[si tableobject]];
    
    
}

//tableobject重新整理3=>主要是上節點資料夾上下面的資料匯入整合到節點上
-(void)update_all_tree_folder_tableobject_refresh:(NSUInteger )inx{
    //i:0 表示系統的群組
    //i:1 表示自設群組
    
    //  for (int i=0; i<[Para_SLT_Paraent_Array count]; i++) {
    
        //為何i=1 表示只有更新自設群組的結構 其他結構不進行計算 很重要 會影響速度
        [self tree_folder_tableobject_refresh: [Para_SLT_Paraent_Array objectAtIndex:inx] ];
    
    //  }
    
}

#pragma mark -
#pragma mark 資料節點的增加與搜尋

//輸入資料字典來檢查是否已經有存在記憶體中，如果沒有則新增，並且回傳此代碼之下的資料子物件位置
//資料模型與樹狀結構得聯結點就是透過此函數(將陣列資料轉成要呈現的樹狀資料)
-(Data_Object *)add_data_object_dic_data:(NSMutableDictionary *)dic_data {
    
    //1.從字典資料裡找出股票代碼
    NSString *search;
    search=[dic_data objectForKey:DB_object_sqlite_basic_code];
    
    //2.針對每個資料陣列裡的字典去找是否有相同的代碼
    NSUInteger idx = [ data_object_arrary  indexOfObjectPassingTest:
                      ^ BOOL (Data_Object* obj, NSUInteger idx, BOOL *stop)
                      {
                          BOOL result = ([[[obj table_data] objectForKey:DB_object_sqlite_basic_code]  isEqualToString:search ]);
                          *stop = result;
                          return result;
                          
                      }];
    
    //3.針對搜尋結果
    /*
    //限定data_object_arrary數目
    if ([data_object_arrary count]>10) {
        [data_object_arrary removeObjectAtIndex:0];
     
    }
    NSLog(@"限定data_object_arrary數目=%ld",[data_object_arrary count]);
    */
    
    
    if (idx ==NSNotFound) {
        
        //原本的資料陣列內沒有此字典 新增一個
        
        if (![self calculate_property_all]) {
            [self setCalculate_property_all:[RLCalculationMethod calculate_method_property]];
            
        } 
        Data_Object *addodb=[[Data_Object alloc] init_data :dic_data datamodel:self _calculate_property_all:calculate_property_all];
        
        [data_object_arrary addObject:addodb];
        
        //回傳物件位置
        [addodb autorelease];
        return  addodb  ;
    }
    else{
       
        //如果有此個別資料 傳回位置
        Data_Object *obj=[data_object_arrary  objectAtIndex:idx];      
        
            
        return obj;
             
        
    }
    
    
    
}

//輸入股票代碼，傳回資料子物件的位置
-(Data_Object *)object_data_arrary_object_from_code_datamodel:(NSString *)code{
    
    NSString *search;
    search=code;                
    NSUInteger idx = [ data_object_arrary  indexOfObjectPassingTest:
                      ^ BOOL (Data_Object* obj, NSUInteger idx, BOOL *stop)
                      {
                          BOOL result = ([[[obj table_data] objectForKey:DB_object_sqlite_basic_code]  isEqualToString:search ]);
                          *stop = result;
                          return result;                                      
                          
                      }];                
    
    
    if (idx ==NSNotFound) {
        return nil;      
    }
    else{
        Data_Object *obj=[ data_object_arrary  objectAtIndex:idx];      
        return obj;
        
    }
    
}
//輸入代碼，個別資料物件傳回排序位置
-(NSUInteger)index_data_arrary_object_from_code_datamodel:(NSString *)code{
    
    NSString *search;
    search=code;                
    
    NSUInteger idx = [ data_object_arrary  indexOfObjectPassingTest:
                      ^ BOOL (Data_Object* obj, NSUInteger idx, BOOL *stop)
                      {
                          BOOL result = ([[[obj table_data] objectForKey:DB_object_sqlite_basic_code]  isEqualToString:search ]);
                          *stop = result;
                          return result;                                      
                          
                      }];                
    
    return idx;
    
    
    
}
//列印出所有的資料結構 檢測使用
-(void)list_data_structure{
    
    for (int i=0; i<[data_object_arrary count]; i++) {
         NSLog(@"dataobject = %@",  [[(Data_Object *)[data_object_arrary objectAtIndex:i] table_data] objectForKey:DB_object_sqlite_basic_code]  );        
        
    }
    
        
 

}

#pragma mark -
#pragma mark 產生陣列結構plist array 資料模式
//2.輸入多個國家代碼 並且將資料存到catches 目錄上 且傳回國家們節點
-(NSArray *)create_write_countrys_node:(NSArray *)countrys{
    
     
    //歷史檔案路徑
    NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];	
    NSString *Path_Para_SLT_system  ; 
    Path_Para_SLT_system=[prefs objectForKey:Defaults_Path_Para_SLT_system_Data];    
    
    //系統存檔檔名
    NSString *filename=[NSString stringWithFormat:@"Para_SLT_system_%@.plist",datasource];    
    
    //此陣列主要作用是從檔案取出陣列
     NSArray *read_array;                                 
       
    //此陣列主要是用來將所設定的資料存到檔案使用                           
    NSMutableArray *write_array;                                
    write_array=[[NSMutableArray alloc] init];
    
    //使用程式碼製作系統內定的樹狀結構
    for (NSString *country in countrys ) {
        [write_array addObject:[self create_country_node:country]];
    }
    
   
     
    //將系統產生的名單放在Caches目錄下
    //存檔
    
    NSLog(@"存檔=%@",[Path_Para_SLT_system stringByAppendingPathComponent:filename] );                                
    
    [write_array writeToFile:[Path_Para_SLT_system stringByAppendingPathComponent:filename] atomically:YES];                                
    [write_array release];
    
    //取檔
    read_array=[NSArray arrayWithContentsOfFile:[Path_Para_SLT_system stringByAppendingPathComponent:filename]];
    return read_array;
    
    

}
//1.製作國家節點
-(NSMutableDictionary *)create_country_node:(NSString *)country{
    
    NSMutableDictionary *node_country = [NSMutableDictionary dictionaryWithCapacity:2];
    
    [node_country setObject:country forKey:Node_identifier];
    [node_country setObject:country forKey:Node_title]; 
    [node_country setObject:@"Tree_Folder.png" forKey:Node_icon];
    [node_country setObject:[NSNumber numberWithInt:14] forKey:Node_badgeValue]; 
    [node_country setObject:[NSNumber numberWithBool: YES] forKey:Node_isUseForGroup];                               
    [node_country setObject: [[[NSMutableArray alloc] init] autorelease]  forKey:Node_Array_StockData];                                    
    [node_country setObject:[self sqlite_data_to_node:country]  forKey:Node_children];                                    
    
    return node_country;
}
//0.輸入國家代碼 從sqlite取出股票資料 並且將這些資料轉成產業節點
-(NSMutableArray *)sqlite_data_to_node:(NSString *)country{
    //資料庫取用陣列
    NSMutableArray *code_array;	  
    NSMutableArray *code_array_Yahoo;	    
    NSMutableArray *code_array_Google;	
    NSMutableArray *code_array_Bloomberg;
    
    NSMutableArray *symbol_array;	 
    NSMutableArray *country_array;	    
    NSMutableArray *name_array;
    NSMutableArray *class_array; //分類 產業分類用於自選股群組
    NSMutableArray *id_class_array; //分類 產業分類用於最佳化	  
    NSMutableArray *classd; //獨立產業分類表      
    NSMutableArray *timezone_array; //時區
    
    //1.從sql資料庫取出資料
    {
        //初始化
        symbol_array=	[[NSMutableArray alloc] init];
          
        
        code_array=	[[NSMutableArray alloc] init];         
        code_array_Yahoo=	[[NSMutableArray alloc] init]; 
        code_array_Google=	[[NSMutableArray alloc] init]; 
        code_array_Bloomberg=	[[NSMutableArray alloc] init];         
        
        country_array=	[[NSMutableArray alloc] init];    
        name_array=	[[NSMutableArray alloc] init];
        class_array=[[NSMutableArray alloc] init];
        id_class_array=[[NSMutableArray alloc] init];		
        classd=[[NSMutableArray alloc] init];          
        timezone_array=[[NSMutableArray alloc] init]; 
        
        //NSString *ver;
        //ver=[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
        //ver=[ver stringByReplacingOccurrencesOfString:@"." withString:@"_"];
       
       // NSString *DisplayName;
       // DisplayName=[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
        
       // NSString *target_ProductName= [NSString stringWithFormat:@"Target_%@",DisplayName] ;
        
        NSString *filename;
        //filename=[NSString stringWithFormat: @"%@_data_",target_ProductName];
        
        filename=[File_Name_Path file_name_sqlite];
       
        NSString *filenamexx;
        filenamexx=@"sqlite3";
        NSString *fullfilename;
        fullfilename=[filename stringByAppendingString:@"."];
        fullfilename=[fullfilename stringByAppendingString:filenamexx];
         
        //NSLog(@"資料庫=%@",filename);
        
        //資料庫啓動ff
        DBHelper *helper =[DBHelper newInstance:filename andEXT:filenamexx andfullname:fullfilename];
        
        sqlite3 *database = [helper openDatabase]; 
        sqlite3_stmt *stm;
        
        //ＳＱL語法
        NSString *tsql;
        const char *sql = NULL;	
        
        if([datasource isEqualToString:id_Yahoo_WEB]){
            tsql=@"SELECT id,Code_Yahoo,Symbol_Yahoo,Country_Yahoo,Lname,Ename,Class,Code_Bloomberg,Code_Google,TimeZone FROM ";
        } 
        else if([datasource isEqualToString:id_Yahoo_Mobile]){
            tsql=@"SELECT id,Code_Yahoo,Symbol_Yahoo,Country_Yahoo,Lname,Ename,Class,Code_Bloomberg,Code_Google,TimeZone FROM ";
        }
        else if([datasource isEqualToString:id_MultiServer_GY]){
            tsql=@"SELECT id,Code_Yahoo,Symbol_Yahoo,Country_Yahoo,Lname,Ename,Class,Code_Bloomberg,Code_Google,TimeZone FROM ";
        }
        else if([datasource isEqualToString:id_Google]){
            tsql=@"SELECT id,Code_Google,Symbol_Google,Country_Google,Lname,Ename,Class,Code_Yahoo,Code_Bloomberg,TimeZone FROM ";
        } 
        else if([datasource isEqualToString:id_Bloomberg]){
            tsql=@"SELECT id,Code_Bloomberg,Symbol_Bloomberg,Country_Bloomberg,Lname,Ename,Class,Code_Yahoo,Code_Google,TimeZone FROM ";
        } 
        else {
            tsql=@"SELECT id,Code_Yahoo,Symbol_Yahoo,Country_Yahoo,Lname,Ename,Class,TimeZone FROM ";
        }   
        
        tsql=[tsql stringByAppendingString:country];
        sql=[tsql UTF8String];        
        
        
        //取出資料
        if(sqlite3_prepare_v2(database, sql, strlen(sql), &stm, NULL)== SQLITE_OK) {
             while(sqlite3_step(stm) ==SQLITE_ROW)
            {
                //檢查是否為 NA_code 
                char *field_check=(char *)sqlite3_column_text(stm, 1);
                NSString *code_check;
                code_check=[[[NSString alloc] initWithUTF8String: field_check] autorelease];                
               
                if (![code_check isEqualToString:@"NA_Code"]) {
                    //表示是有效的代碼
                    
                    //1:Code
                    char *field1=(char *)sqlite3_column_text(stm, 1);
                    NSString *ss1;
                    ss1=[[NSString alloc] initWithUTF8String: field1];
                    [code_array addObject:ss1];		
                    [ss1 release];
                    
                    //2:Symbol
                    char *field2=(char *)sqlite3_column_text(stm, 2);            
                    NSString *ss2;
                    ss2=[[NSString alloc] initWithUTF8String: field2];
                    [symbol_array addObject:ss2];		
                    [ss2 release];            
                    
                    
                    //3:Country
                    char *field3=(char *)sqlite3_column_text(stm, 3);
                    NSString *ss3;
                    ss3=[[NSString alloc] initWithUTF8String:  field3];
                    [country_array addObject:ss3];			
                    [ss3 release];
                    
                    
                    //4:lname
                    char *field4=(char *)sqlite3_column_text(stm, 4);
                    NSString *ss4;
                    ss4=[[NSString alloc] initWithUTF8String:  field4];
                    [name_array addObject:ss4];			
                    [ss4 release];            
                    
                    //6:class
                    char *field6=(char *)sqlite3_column_text(stm, 6);
                    NSString *ss6;
                    ss6=[[NSString alloc] initWithUTF8String: field6];
                    [class_array addObject:ss6]	;			
                    [id_class_array addObject:ss6]	;					
                    //6.1:附帶產生產業類別陣列
                    if([classd indexOfObject:ss6]==NSNotFound)
                    {
                        [classd addObject:ss6];
                    }
                    [ss6 release]; 
                    
                    if([datasource isEqualToString:id_Yahoo_WEB]){
                        //yahoo
                        [code_array_Yahoo addObject:ss1];
                        
                        //bloomberg
                        char *field7=(char *)sqlite3_column_text(stm, 7);
                        NSString *ss7;
                        ss7=[[NSString alloc] initWithUTF8String: field7];
                        [code_array_Bloomberg addObject:ss7];		
                        [ss7 release];                    
                        
                        //google
                        char *field8=(char *)sqlite3_column_text(stm, 8);
                        NSString *ss8;
                        ss8=[[NSString alloc] initWithUTF8String: field8];
                        [code_array_Google addObject:ss8];		
                        [ss8 release];                          
                        
                        
                    } 
                    else if([datasource isEqualToString:id_Yahoo_Mobile]){
                        //yahoo
                        [code_array_Yahoo addObject:ss1];
                        
                        //bloomberg
                        char *field7=(char *)sqlite3_column_text(stm, 7);
                        NSString *ss7;
                        ss7=[[NSString alloc] initWithUTF8String: field7];
                        [code_array_Bloomberg addObject:ss7];		
                        [ss7 release];                    
                        
                        //google
                        char *field8=(char *)sqlite3_column_text(stm, 8);
                        NSString *ss8;
                        ss8=[[NSString alloc] initWithUTF8String: field8];
                        [code_array_Google addObject:ss8];		
                        [ss8 release];                     
                        
                        
                    }
                    else if([datasource isEqualToString:id_MultiServer_GY]){
                        //yahoo
                        [code_array_Yahoo addObject:ss1];
                        
                        //bloomberg
                        char *field7=(char *)sqlite3_column_text(stm, 7);
                        NSString *ss7;
                        ss7=[[NSString alloc] initWithUTF8String: field7];
                        [code_array_Bloomberg addObject:ss7];
                        [ss7 release];
                        
                        //google
                        char *field8=(char *)sqlite3_column_text(stm, 8);
                        NSString *ss8;
                        ss8=[[NSString alloc] initWithUTF8String: field8];
                        [code_array_Google addObject:ss8];
                        [ss8 release];
                        
                        
                    }
                    
                    
                    else if([datasource isEqualToString:id_Google]){
                        
                        //google
                        [code_array_Google addObject:ss1];
                        
                        //yahoo
                        char *field7=(char *)sqlite3_column_text(stm, 7);
                        NSString *ss7;
                        ss7=[[NSString alloc] initWithUTF8String: field7];
                        [code_array_Yahoo addObject:ss7];		
                        [ss7 release];                    
                        
                        //bloomberg
                        char *field8=(char *)sqlite3_column_text(stm, 8);
                        NSString *ss8;
                        ss8=[[NSString alloc] initWithUTF8String: field8];
                        [code_array_Bloomberg addObject:ss8];		
                        [ss8 release];                        
                        
                        
                        
                    } 
                    else if([datasource isEqualToString:id_Bloomberg]){
                        //bloomberg
                        [code_array_Bloomberg addObject:ss1];
                        
                        //yahoo
                        char *field7=(char *)sqlite3_column_text(stm, 7);
                        NSString *ss7;
                        ss7=[[NSString alloc] initWithUTF8String: field7];
                        [code_array_Yahoo addObject:ss7];		
                        [ss7 release];                    
                        
                        //google
                        char *field8=(char *)sqlite3_column_text(stm, 8);
                        NSString *ss8;
                        ss8=[[NSString alloc] initWithUTF8String: field8];
                        [code_array_Google addObject:ss8];		
                        [ss8 release];                           
                        
                        
                        
                    } 
                    
                    //4:時區
                    char *field9=(char *)sqlite3_column_text(stm, 9);
                    NSString *ss9;
                    ss9=[[NSString alloc] initWithUTF8String:  field9];
                    [timezone_array addObject:ss9];			
                    [ss9 release];                     
                    
                    
                    
                    
                    
                }
                
                             
                
                
                
                
                
            }
            
        }
        //結束查詢作業
        sqlite3_finalize(stm);        
        
    }
    
    
    //傳出去的暫存陣列
    NSMutableArray *temp_class_code_array=[[NSMutableArray alloc] init];    
    //2.
    {
         
        for (NSString *classname in classd  ) {
            //建立每個產業裡該有哪些股票
            NSMutableDictionary *document_1_1 = [NSMutableDictionary dictionaryWithCapacity:2];
            
            [document_1_1 setObject:classname                       forKey:Node_identifier];
            [document_1_1 setObject:classname                       forKey:Node_title];                            
            [document_1_1 setObject:@"Tree_Document.png"            forKey:Node_icon];
            [document_1_1 setObject:[NSNumber numberWithInt:11]     forKey:Node_badgeValue]; 
            [document_1_1 setObject:@""                             forKey:Node_children];  
            [document_1_1 setObject:[NSNumber numberWithBool: NO]   forKey:Node_isUseForGroup];             
            
            //Node_Array_StockData 建立此節點有哪些股票 並且有哪些股票資訊涵蓋在裡面
            {
                NSMutableArray *document_1_1_tablecode=[[NSMutableArray alloc] init];        
                for (int i=0;i<[class_array count];i++) {
                    
                    if ([classname isEqualToString:[class_array objectAtIndex:i] ]) {
                        
                        NSMutableDictionary *object_dictionary_data_1=[NSMutableDictionary dictionaryWithCapacity:2];
                        
                        //標記：報價-欄位資料來源為sqlite資料檔案中輸入 4.從sqlite取出資料檔
                        //=========================                
                        [object_dictionary_data_1 setObject:[code_array objectAtIndex:i]    forKey:DB_object_sqlite_basic_code];
                        
                         [object_dictionary_data_1 setObject:[code_array_Yahoo objectAtIndex:i]    forKey:DB_object_sqlite_basic_code_Yahoo];                        
                         [object_dictionary_data_1 setObject:[code_array_Google objectAtIndex:i]    forKey:DB_object_sqlite_basic_code_Google];
                        [object_dictionary_data_1 setObject:[code_array_Bloomberg objectAtIndex:i]    forKey:DB_object_sqlite_basic_code_Bloomberg];
                        
                        [object_dictionary_data_1 setObject:[symbol_array objectAtIndex:i]  forKey:DB_object_sqlite_basic_symbol];
                        [object_dictionary_data_1 setObject:[country_array objectAtIndex:i] forKey:DB_object_sqlite_basic_country];                
                        [object_dictionary_data_1 setObject:classname                       forKey:DB_object_sqlite_basic_class];                
                        [object_dictionary_data_1 setObject:[name_array objectAtIndex:i]    forKey:DB_object_sqlite_basic_name_english];                     
                        [object_dictionary_data_1 setObject:[name_array objectAtIndex:i]    forKey:DB_object_sqlite_basic_name_chinese];   
                        [object_dictionary_data_1 setObject:[timezone_array objectAtIndex:i]    forKey:DB_object_sqlite_basic_timezone];                            
                        [object_dictionary_data_1 setObject:@"樣本1 a"    forKey:DB_object_sqlite_basic_sample1];                         
                        [object_dictionary_data_1 setObject:@"樣本2 a"    forKey:DB_object_sqlite_basic_sample2];                        
                        
                        
                        //非sqlite取出 而是自設的欄位 這是多出來 記住完成股票數量之後要刪除 
                        //[object_dictionary_data_1 setObject:[NSNumber numberWithInt:0]    forKey: 
                        
                        //=========================                
                        [document_1_1_tablecode addObject:object_dictionary_data_1];
                        
                    }
                     
                }
                
                [document_1_1 setObject:document_1_1_tablecode           forKey:Node_Array_StockData];            
                [document_1_1_tablecode release];
            }
            //Node_Array_StockData_for_table 建立此節點有哪些股票 並且有哪些股票資訊涵蓋在裡面
            {
                NSMutableArray *document_1_1_tablecode=[[NSMutableArray alloc] init];        
                for (int i=0;i<[class_array count];i++) {
                    
                    if ([classname isEqualToString:[class_array objectAtIndex:i] ]) {
                        
                        NSMutableDictionary *object_dictionary_data_1=[NSMutableDictionary dictionaryWithCapacity:2];
                        
                        
                        //=========================                
                        [object_dictionary_data_1 setObject:[code_array objectAtIndex:i]    forKey:DB_object_sqlite_basic_code];
                        
                        [object_dictionary_data_1 setObject:[code_array_Yahoo objectAtIndex:i]    forKey:DB_object_sqlite_basic_code_Yahoo];                        
                        [object_dictionary_data_1 setObject:[code_array_Google objectAtIndex:i]    forKey:DB_object_sqlite_basic_code_Google];
                        [object_dictionary_data_1 setObject:[code_array_Bloomberg objectAtIndex:i]    forKey:DB_object_sqlite_basic_code_Bloomberg];
                         
                        //非sqlite取出 而是自設的欄位
                                               
                        //----------------------------------------------------------------------------                        
                        
                        
                         //----------------------------------------------------------------------------                        
                        //標記：利用欄位屬性定義自動完成程式碼 從sqlite取出資料時 初始化onlyfortableObject
                        for (NSMutableDictionary *tc in  [table_column_object_array table_column_array] ) {
                            //取出所有欄位屬性資料
                            
                            if ([[tc objectForKey:Table_Column_data_loactaionPath] isEqualToString:loactaionPath_tableobject_data_array_onlyfortableObject]) {
                                
                                NSString *sTable_Column_Key =   [tc objectForKey:Table_Column_Key];                
                                                  
                                
                                //判斷不同資料格式
                                if (![[tc objectForKey:Table_Column_cell_date_string_formate] isEqualToString:@""]) {
                                    //日期格式
                                       [object_dictionary_data_1 setObject:[NSDate date]    forKey:sTable_Column_Key];  
                                    
                                    
                                }
                                else if (![[tc objectForKey:Table_Column_cell_number_string_formate] isEqualToString:@""]){
                                    //數字格式
                                       [object_dictionary_data_1 setObject:[NSNumber numberWithInt:0]    forKey:sTable_Column_Key];  
                                    
                                    
                                }
                                else {
                                    //文字格式
                                       [object_dictionary_data_1 setObject:@""    forKey:sTable_Column_Key];                                      
                                                                        
                                }
                                
                                
                                
                                
                            }
                                       
                            
                        }
                         
                        //=========================                
                        [document_1_1_tablecode addObject:object_dictionary_data_1];
                        
                    }
                    
                }
                
                [document_1_1 setObject:document_1_1_tablecode           forKey:Node_Array_StockData_for_table];            
                [document_1_1_tablecode release];
            }            
             
            [temp_class_code_array addObject:document_1_1];
           
            
        }
        
        
        //釋放
        [temp_class_code_array autorelease];
        [timezone_array release];
        [code_array_Yahoo release];
        [code_array_Google release];
        [code_array_Bloomberg release];
        [code_array release];    
        [symbol_array release];
        [country_array release];
        [name_array release];
        [class_array release];
        [id_class_array release];		
        [classd release];     
        
    
    }
         
    return temp_class_code_array;
}

#pragma mark -
#pragma mark 代碼名稱搜尋

-(NSArray *)serach_data:(NSString *)datasourcea searching:(NSString *)serach_strings{
    
    
    
    if ([datasourcea isEqualToString:id_Yahoo_WEB]) {
        Yahoo_Search_WEB *xbs=[[[Yahoo_Search_WEB alloc] init_identify:@"17243a4e72c7eadd0e9823cd887f97212efa43fa"] autorelease];
        
        return [xbs get_search_array_data:serach_strings ];        
        
    }
    else if ([datasourcea isEqualToString:id_Yahoo_Mobile]) {
         
        Yahoo_Search_Mobile *xbs=[[[Yahoo_Search_Mobile alloc] init_identify:@"17243a4e72c7eadd0e9823cd887f97212efa43fa"] autorelease];
        return [xbs get_search_array_data:serach_strings ];        
         
    }    
    else if ([datasourcea isEqualToString:id_MultiServer_GY]) {
        
        Multi_Server_GY_Search *xbs=[[[Multi_Server_GY_Search alloc] init_identify:@"17243a4e72c7eadd0e9823cd887f97212efa43fa"] autorelease];
        return [xbs get_search_array_data:serach_strings ];
        
    }
    else if ([datasourcea isEqualToString:id_Google]) {
        Google_Search *xbs=[[[Google_Search alloc] init_identify:@"17243a4e72c7eadd0e9823cd887f97212efa43fa"] autorelease];
        
        return [xbs get_search_array_data:serach_strings ];        
        
        
        
    }
    else if ([datasourcea isEqualToString:id_Bloomberg]) {
        
        XML_Bloomberg_Search *xbs=[[[XML_Bloomberg_Search alloc] init_identify:@"17243a4e72c7eadd0e9823cd887f97212efa43fa"] autorelease];
        
        return [xbs get_search_array_data:serach_strings count:100];
        
        
    }    
    else {
         return nil;
    }
   

}

#pragma mark -
#pragma mark 歷史資料 開始回補

-(void)His_Data_Start:(NSString *)code{
    
    if ([datasource isEqualToString:id_Yahoo_WEB]) {
        /*資料特點
          最長可以到40年
         
         */
        if ([queue_his_data operationCount] <Max_OperationQueue_his_data) {
            
            //1.移除代碼
            if ([unstart_code_array_his_data indexOfObject:code]!=NSNotFound) {
                //表示有此代碼 就要移除
                [unstart_code_array_his_data removeObject:code];
                
            }             
            
            
            //2.檢查判斷記憶體兩個小時內是否已經有取得歷史資料   
            Data_Object *obj=[self object_data_arrary_object_from_code_datamodel:code];            
            BOOL isRestore_history_data;
            isRestore_history_data=YES;
            if ([obj his_data_get_date]!=nil && [obj his_data_get_date] ) {
                
                //如果記憶體有歷史資料檔案陣列以及最近更新或取的歷史資料時間
                
                NSDate *his_get_date=[obj his_data_get_date];
                //NSLog(@"最近更新或取的歷史資料時間=%@",his_get_date);
                
                NSDate *now;
                now=[NSDate date];
                NSTimeInterval secondsBetween = [now timeIntervalSinceDate:his_get_date];
                int ii=secondsBetween;
                
                //NSLog(@"目前時間與更新或取的歷史資料時間差值=%i",ii);
                
                int max_sec;
                max_sec=60*60*Max_Diff_Hour_To_Get_History_Data;
                
                if (ii<max_sec) {
                    //表示在合理時間內不用回補
                    isRestore_history_data=NO;
                }
                
            } 
            
            //3.需要網路上下載歷史資料
            if (YES) {
                
                //建立執行緒事件
                
                //取出要寫入資料的檔名：採用yahoo代碼    
                //Data_Object *obj=[self object_data_arrary_object_from_code_datamodel:code];
                
                NSString *yahoo_code;
                yahoo_code=[[obj table_data] objectForKey:DB_object_sqlite_basic_code_Yahoo];
                
                NSString *timezone=[[obj table_data] objectForKey:DB_object_sqlite_basic_timezone];                
                //報價表上的時間 用來與歷史資料檔案最後一天比較 看相差幾天來進行回補
                NSDate *table_quote_date;
                table_quote_date=[[obj table_data] objectForKey:DB_object_quote_all_datetime];                
                
                if (yahoo_code && timezone && table_quote_date) {
                    //要確定此三項數據非 null 才可以進入   
                   
                    //針對不同資料源要修改的地方
                    {
                       
                        
                        Yahoo_Web_History *plo = [[Yahoo_Web_History alloc] init_With_Code:code file_code:yahoo_code table_quote_date:table_quote_date timezone:timezone is_have_to_reload_data:isRestore_history_data] ;
                        
                        //設定執行緒委託
                        [plo setDelgeate:self];
                        
                        //加入到執行工作序上
                        [queue_his_data addOperation:plo];
                        [plo release];                  
                    
                        
                    }
                    
                    //並且通知狀態列 已經有新的工作執行緒出現
                    {
                        NSMutableDictionary *document;
                        document=[[NSMutableDictionary alloc] init];
                       
                                                
                         
                        [document setObject:[NSNumber numberWithInt: [queue_quote operationCount]] forKey:His_data_reload_ongoing];
                        
                        NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
                        [nc postNotificationName:NOT_his_begin_APP1_Start_WindowController
                                          object:self
                                        userInfo: document   ];                 
                        [document release];
                        
                    }                    
                    
                    
                }
                else {
                    NSLog(@"資料尚未搜集完全所以無法進入下載歷史資料執行緒");
                    NSLog(@"yahoo_code=%@",yahoo_code);
                    NSLog(@"timezone=%@",timezone);
                    NSLog(@"aa table_quote_date=%@",table_quote_date);
                   
                    if ( [unstart_code_array_his_data count] >0 || [queue_his_data operationCount]>1 ) {
                        
                        //列印出尚未進入排成的代碼
                        /*
                        for (NSString *c in unstart_code_array_his_data) {
                            NSLog(@"尚未進入排成的代碼=%@",c);
                        }
                        */
                        
                        [self His_Data_Start:[unstart_code_array_his_data objectAtIndex:0] ];
                        
                        
                    }
                    else{
                       NSLog(@"終止回補歷史資料=%@",code);
                    }
                    
                    
                }
               
                
                
                
            }
            //不用回補歷史資料 直接通知中心更新走勢圖 只傳遞代碼            
            else {
              
                
            }  
           
            
       } 
        //超過最大範圍限制 尚未進入排程的代碼
        else {
           
            if ([unstart_code_array_his_data indexOfObject:code]==NSNotFound) {
                //避免重復
                //[unstart_code_array_his_data addObject:code];  
                //將新加入的插入到第一個主要是要讓最近加入的越早取得歷史資料
                [unstart_code_array_his_data insertObject:code atIndex:0];
            } 
            else {
                 
                //之前已經有排入 所以將此代碼移到最前面
                [unstart_code_array_his_data removeObject:code];
                [unstart_code_array_his_data insertObject:code atIndex:0];     
                 
            }
            
            
       }       
    }
    else if ([datasource isEqualToString:id_Yahoo_Mobile]) {
        /*資料特點
         最長可以到3年
         
         */
        if ([queue_his_data operationCount] <Max_OperationQueue_his_data) {
            
            //1.移除代碼
            if ([unstart_code_array_his_data indexOfObject:code]!=NSNotFound) {
                //表示有此代碼 就要移除
                [unstart_code_array_his_data removeObject:code];
                
            }             
            
            
            
            //2.檢查判斷記憶體兩個小時內是否已經有取得歷史資料   
            Data_Object *obj=[self object_data_arrary_object_from_code_datamodel:code];            
            BOOL isRestore_history_data;
            isRestore_history_data=YES;
            
            if ( [obj his_data_get_date] ) {
                
                //如果記憶體有歷史資料檔案陣列以及最近更新或取的歷史資料時間
                
                NSDate *his_get_date=[obj his_data_get_date];
                //NSLog(@"最近更新或取的歷史資料時間=%@",his_get_date);
                
                NSDate *now;
                now=[NSDate date];
                NSTimeInterval secondsBetween = [now timeIntervalSinceDate:his_get_date];
                int ii=secondsBetween;
                
                //NSLog(@"目前時間與更新或取的歷史資料時間差值=%i",ii);
                
                int max_sec;
                max_sec=60*60*Max_Diff_Hour_To_Get_History_Data;
                
                if (ii<max_sec) {
                    //表示在合理時間內不用回補
                    isRestore_history_data=NO;
                }
                
            } 
            
            //3.需要網路上下載歷史資料
            if (YES) {
                           
                
                //建立執行緒事件
                
                //取出要寫入資料的檔名：採用yahoo代碼    
                //Data_Object *obj=[self object_data_arrary_object_from_code_datamodel:code];
                
                NSString *yahoo_code;
                yahoo_code=[[obj table_data] objectForKey:DB_object_sqlite_basic_code_Yahoo];
                
                NSString *timezone=[[obj table_data] objectForKey:DB_object_sqlite_basic_timezone];                
                //報價表上的時間 用來與歷史資料檔案最後一天比較 看相差幾天來進行回補
                NSDate *table_quote_date;
                table_quote_date=[[obj table_data] objectForKey:DB_object_quote_all_datetime];                
                if (yahoo_code && timezone && table_quote_date) {
                    //要確定此三項數據非 null 才可以進入 
                    //針對不同資料源要修改的地方
                    {
                        
                        Yahoo_Mobile_History *plo = [[Yahoo_Mobile_History alloc] init_With_Code:code file_code:yahoo_code table_quote_date:table_quote_date timezone:timezone is_have_to_reload_data:isRestore_history_data] ;
                        
                        //設定執行緒委託
                        [plo setDelgeate:self];
                        
                        //加入到執行工作序上
                        [queue_his_data addOperation:plo];
                        [plo release];                  
                        
                    }
                    
                    
                    //並且通知狀態列 已經有新的工作執行緒出現
                    {
                        NSMutableDictionary *document;
                        document=[[NSMutableDictionary alloc] init];
                        
                        
                         
                        [document setObject:[NSNumber numberWithInt: [queue_quote operationCount]] forKey:His_data_reload_ongoing];     
                        
                        NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
                        [nc postNotificationName:NOT_his_begin_APP1_Start_WindowController
                                          object:self
                                        userInfo: document   ];                 
                        [document release];
                        
                    }                    
                    
                }
                else {
                      NSLog(@"資料尚未搜集完全所以無法進入下載歷史資料執行緒");
                    if ( [unstart_code_array_his_data count] >0 || [queue_his_data operationCount]>1 ) {
                        
                        //列印出尚未進入排成的代碼
                        /*
                        for (NSString *c in unstart_code_array_his_data) {
                            NSLog(@"尚未進入排成的代碼=%@",c);
                        }
                        */
                        
                        [self His_Data_Start:[unstart_code_array_his_data objectAtIndex:0] ];
                        
                        
                    }
                    else{
                        NSLog(@"終止回補歷史資料=%@",code);
                    }
                    
                }
               
                
            }
            //不用回補歷史資料 直接通知中心更新走勢圖 只傳遞代碼            
            else {
             
                
            }  
            
            
        } 
        //尚未進入排程的代碼
        else {
            
            if ([unstart_code_array_his_data indexOfObject:code]==NSNotFound) {
                //避免重復
                //[unstart_code_array_his_data addObject:code];  
                //將新加入的插入到第一個主要是要讓最近加入的越早取得歷史資料
                [unstart_code_array_his_data insertObject:code atIndex:0];
            } 
            else {
                
                //之前已經有排入 所以將此代碼移到最前面
                
                 
                [unstart_code_array_his_data removeObject:code];
                  
                [unstart_code_array_his_data insertObject:code atIndex:0];
               
            }
            
            
        }      
                 
    }
    else if ([datasource isEqualToString:id_MultiServer_GY]) {
        /*資料特點
         最長可以到40年
         
         */
        if ([queue_his_data operationCount] <Max_OperationQueue_his_data) {
            
            //1.移除代碼
            if ([unstart_code_array_his_data indexOfObject:code]!=NSNotFound) {
                //表示有此代碼 就要移除
                [unstart_code_array_his_data removeObject:code];
                
            }
            
            
            //2.檢查判斷記憶體兩個小時內是否已經有取得歷史資料
            Data_Object *obj=[self object_data_arrary_object_from_code_datamodel:code];
            BOOL isRestore_history_data;
            isRestore_history_data=YES;
            if ([obj his_data_get_date]!=nil && [obj his_data_get_date] ) {
                
                //如果記憶體有歷史資料檔案陣列以及最近更新或取的歷史資料時間
                
                NSDate *his_get_date=[obj his_data_get_date];
                //NSLog(@"最近更新或取的歷史資料時間=%@",his_get_date);
                
                NSDate *now;
                now=[NSDate date];
                NSTimeInterval secondsBetween = [now timeIntervalSinceDate:his_get_date];
                int ii=secondsBetween;
                
                //NSLog(@"目前時間與更新或取的歷史資料時間差值=%i",ii);
                
                int max_sec;
                max_sec=60*60*Max_Diff_Hour_To_Get_History_Data;
                
                if (ii<max_sec) {
                    //表示在合理時間內不用回補
                    isRestore_history_data=NO;
                }
                
            }
            
            //3.需要網路上下載歷史資料
            if (YES) {
                
                //建立執行緒事件
                
                //取出要寫入資料的檔名：採用yahoo代碼
                //Data_Object *obj=[self object_data_arrary_object_from_code_datamodel:code];
                
                NSString *yahoo_code;
                yahoo_code=[[obj table_data] objectForKey:DB_object_sqlite_basic_code_Yahoo];
                
                NSString *timezone=[[obj table_data] objectForKey:DB_object_sqlite_basic_timezone];
                //報價表上的時間 用來與歷史資料檔案最後一天比較 看相差幾天來進行回補
                NSDate *table_quote_date;
                table_quote_date=[[obj table_data] objectForKey:DB_object_quote_all_datetime];
                
                
                if (yahoo_code && timezone && table_quote_date) {
                    //要確定此三項數據非 null 才可以進入
                    
                    //針對不同資料源要修改的地方
                    {
                        
                        
                        Multi_Server_GY_History *plo = [[Multi_Server_GY_History alloc] init_With_Code:code file_code:yahoo_code table_quote_date:table_quote_date timezone:timezone is_have_to_reload_data:isRestore_history_data] ;
                        
                        //設定執行緒委託
                        [plo setDelgeate:self];
                        
                        //加入到執行工作序上
                        [queue_his_data addOperation:plo];
                        [plo release];
                        
                        
                    }
                    
                    //並且通知狀態列 已經有新的工作執行緒出現
                    {
                        NSMutableDictionary *document;
                        document=[[NSMutableDictionary alloc] init];
                        
                        
                        
                        [document setObject:[NSNumber numberWithInt: [queue_quote operationCount]] forKey:His_data_reload_ongoing];
                        
                        NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
                        [nc postNotificationName:NOT_his_begin_APP1_Start_WindowController
                                          object:self
                                        userInfo: document   ];
                        [document release];
                        
                    }
                    
                    
                }
                else {
                    NSLog(@"資料尚未搜集完全所以無法進入下載歷史資料執行緒");
                    NSLog(@"yahoo_code=%@",yahoo_code);
                    NSLog(@"timezone=%@",timezone);
                    NSLog(@"bb table_quote_date=%@",table_quote_date);
                    
                    if ( [unstart_code_array_his_data count] >0 || [queue_his_data operationCount]>1 ) {
                        
                        //列印出尚未進入排成的代碼
                        /*
                         for (NSString *c in unstart_code_array_his_data) {
                         NSLog(@"尚未進入排成的代碼=%@",c);
                         }
                         */
                         
                        if ([unstart_code_array_his_data count] >0) {
                          [self His_Data_Start:[unstart_code_array_his_data objectAtIndex:0] ];   
                        }
                        
                        
                        
                    }
                    else{
                        NSLog(@"終止回補歷史資料=%@",code);
                    }
                    
                    
                }
                
                
                
                
            }
            //不用回補歷史資料 直接通知中心更新走勢圖 只傳遞代碼
            else {
                
                
            }
            
            
        }
        //超過最大範圍限制 尚未進入排程的代碼
        else {
            
            if ([unstart_code_array_his_data indexOfObject:code]==NSNotFound) {
                //避免重復
                //[unstart_code_array_his_data addObject:code];
                //將新加入的插入到第一個主要是要讓最近加入的越早取得歷史資料
                [unstart_code_array_his_data insertObject:code atIndex:0];
            }
            else {
                
                //之前已經有排入 所以將此代碼移到最前面
                [unstart_code_array_his_data removeObject:code];
                [unstart_code_array_his_data insertObject:code atIndex:0];
                
            }
            
            
        }
    }
    else if ([datasource isEqualToString:id_Google]) {
        /*資料特點
         最長可以到40年
         
         */         
        
        if ([queue_his_data operationCount] <Max_OperationQueue_his_data) {
            //1.移除代碼
            if ([unstart_code_array_his_data indexOfObject:code]!=NSNotFound) {
                //表示有此代碼 就要移除
                [unstart_code_array_his_data removeObject:code];
                
            }                
            //2.限定執行緒數目
            NSLog(@"His_Data_Start_Google=%@",code);
            
            //檢查判斷記憶體兩個小時內是否已經有取得歷史資料   
            Data_Object *obj=[self object_data_arrary_object_from_code_datamodel:code];            
            BOOL isRestore_history_data;
            isRestore_history_data=YES;
            
            if (  [obj his_data_get_date] ) {
                
                //如果記憶體有歷史資料檔案陣列以及最近更新或取的歷史資料時間
                
                NSDate *his_get_date=[obj his_data_get_date];
                //NSLog(@"最近更新或取的歷史資料時間=%@",his_get_date);
                
                NSDate *now;
                now=[NSDate date];
                NSTimeInterval secondsBetween = [now timeIntervalSinceDate:his_get_date];
                int ii=secondsBetween;
                
                //NSLog(@"目前時間與更新或取的歷史資料時間差值=%i",ii);
                
                int max_sec;
                max_sec=60*60*Max_Diff_Hour_To_Get_History_Data;
                
                if (ii<max_sec) {
                    //表示在合理時間內不用回補
                    isRestore_history_data=NO;
                }
                
            } 
            
            //3.需要網路上下載歷史資料
            if (YES) {
                               
                
                //建立執行緒事件
                
                //取出要寫入資料的檔名：採用yahoo代碼    
                Data_Object *obj=[self object_data_arrary_object_from_code_datamodel:code];
                
                NSString *yahoo_code;
                yahoo_code=[[obj table_data] objectForKey:DB_object_sqlite_basic_code_Yahoo];
                
                //報價表上的時間 用來與歷史資料檔案最後一天比較 看相差幾天來進行回補
                NSDate *table_quote_date;
                table_quote_date=[[obj table_data] objectForKey:DB_object_quote_all_datetime];                
               
                NSString *timezone=[[obj table_data] objectForKey:DB_object_sqlite_basic_timezone];                   
              
                if (yahoo_code && timezone && table_quote_date) {
                    //要確定此三項數據非 null 才可以進入 
                    //針對不同資料源要修改的地方
                    {
                        
                        Google_History *plo = [[Google_History alloc] init_With_Code:code file_code:yahoo_code table_quote_date:table_quote_date timezone:timezone is_have_to_reload_data:isRestore_history_data] ;
                        
                        //設定執行緒委託
                        [plo setDelgeate:self];
                        
                        //加入到執行工作序上
                        [queue_his_data addOperation:plo];
                        [plo release];                  
                        
                    }
                    
                    
                    //並且通知狀態列 已經有新的工作執行緒出現
                    {
                        NSMutableDictionary *document;
                        document=[[NSMutableDictionary alloc] init];
                        
                        
                       
                        [document setObject:[NSNumber numberWithInt: [queue_quote operationCount]] forKey:His_data_reload_ongoing];     
                        
                        NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
                        [nc postNotificationName:NOT_his_begin_APP1_Start_WindowController
                                          object:self
                                        userInfo: document   ];                 
                        [document release];
                        
                    }
                    
                    
                }
                else {
                     
                    NSLog(@"aaaa資料尚未搜集完全所以無法進入下載歷史資料執行緒=%@",code);
                    
                    if ( [unstart_code_array_his_data count] >0 || [queue_his_data operationCount]>1 ) {
                        
                        //列印出尚未進入排成的代碼
                        /*
                        for (NSString *c in unstart_code_array_his_data) {
                            NSLog(@"尚未進入排成的代碼=%@",c);
                        }
                        */
                        
                        if ([unstart_code_array_his_data count]>0) {
                             [self His_Data_Start:[unstart_code_array_his_data objectAtIndex:0] ];
                        }
                        
                        
                        
                        
                    }
                    else{
                        NSLog(@"終止回補歷史資料=%@",code);
                    }
                }
                
                               
            }
            else {
                               
            }  
            
            
        }  
        //尚未進入排程的代碼
        else {
            
            if ([unstart_code_array_his_data indexOfObject:code]==NSNotFound) {
                //避免重復
                //[unstart_code_array_his_data addObject:code];  
                //將新加入的插入到第一個主要是要讓最近加入的越早取得歷史資料
                [unstart_code_array_his_data insertObject:code atIndex:0];                
                
                
            } 
            else {
                
                //之前已經有排入 所以將此代碼移到最前面
                [unstart_code_array_his_data removeObject:code];
                [unstart_code_array_his_data insertObject:code atIndex:0];     
                
            }            
            
        }  
    }
    else if ([datasource isEqualToString:id_Bloomberg]) {
        
        /*資料特點
         最長可以到5年
         
         */         
        if ([queue_his_data operationCount] <Max_OperationQueue_his_data) {
            //1.移除代碼
            if ([unstart_code_array_his_data indexOfObject:code]!=NSNotFound) {
                //表示有此代碼 就要移除
                [unstart_code_array_his_data removeObject:code];
                
            }                
            
            
            
            //2.檢查判斷記憶體兩個小時內是否已經有取得歷史資料   
            Data_Object *obj=[self object_data_arrary_object_from_code_datamodel:code];            
            BOOL isRestore_history_data;
            isRestore_history_data=YES;
            
            if (  [obj his_data_get_date] ) {
               
                //如果記憶體有歷史資料檔案陣列以及最近更新或取的歷史資料時間
                
                NSDate *his_get_date=[obj his_data_get_date];
                //NSLog(@"最近更新或取的歷史資料時間=%@",his_get_date);
                
                NSDate *now;
                now=[NSDate date];
                NSTimeInterval secondsBetween = [now timeIntervalSinceDate:his_get_date];
                int ii=secondsBetween;
                
                //NSLog(@"目前時間與更新或取的歷史資料時間差值=%i",ii);
                
                int max_sec;
                max_sec=60*60*Max_Diff_Hour_To_Get_History_Data;
                
                if (ii<max_sec) {
                    //表示在合理時間內不用回補
                    isRestore_history_data=NO;
                }
                
             } 
           
            //3.需要網路上下載歷史資料
            if (YES) {
                           
                
                //建立執行緒事件
                
                //取出要寫入資料的檔名：採用yahoo代碼    
                Data_Object *obj=[self object_data_arrary_object_from_code_datamodel:code];
                
                NSString *yahoo_code;
                yahoo_code=[[obj table_data] objectForKey:DB_object_sqlite_basic_code_Yahoo];
                //報價表上的時間 用來與歷史資料檔案最後一天比較 看相差幾天來進行回補
                NSDate *table_quote_date;
                table_quote_date=[[obj table_data] objectForKey:DB_object_quote_all_datetime];                
                
                NSString *timezone=[[obj table_data] objectForKey:DB_object_sqlite_basic_timezone];                 
                
               
                if (yahoo_code && timezone && table_quote_date) {
                    //要確定此三項數據非 null 才可以進入 
                    //針對不同資料源要修改的地方
                    {
                       
                                              
                        XML_Bloomberg_History *plo = [[XML_Bloomberg_History alloc] init_With_Code:code file_code:yahoo_code table_quote_date:table_quote_date timezone:timezone is_have_to_reload_data:isRestore_history_data] ;
                                                      
                       
                        //設定執行緒委託
                        [plo setDelgeate:self];
                        
                        //加入到執行工作序上
                        [queue_his_data addOperation:plo];
                        [plo release];                 
                    }
                    
                    
                    
                    //並且通知狀態列 已經有新的工作執行緒出現
                    {
                        NSMutableDictionary *document;
                        document=[[NSMutableDictionary alloc] init];
                         
                        
                        
                        [document setObject:[NSNumber numberWithInt: [queue_quote operationCount]] forKey:His_data_reload_ongoing];     
                        
                        NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
                        [nc postNotificationName:NOT_his_begin_APP1_Start_WindowController
                                          object:self
                                        userInfo: document   ];                 
                        [document release];
                        
                    }                    
                    
                    
                }
                else {
                    NSLog(@"資料尚未搜集完全所以無法進入下載歷史資料執行緒");
                    if ( [unstart_code_array_his_data count] >0 || [queue_his_data operationCount]>1 ) {
                        
                        //列印出尚未進入排成的代碼
                        /*
                        for (NSString *c in unstart_code_array_his_data) {
                            NSLog(@"尚未進入排成的代碼=%@",c);
                        }
                        */
                        
                        [self His_Data_Start:[unstart_code_array_his_data objectAtIndex:0] ];
                        
                        
                    }
                    else{
                        NSLog(@"終止回補歷史資料=%@",code);
                    }
                }
                
               
 
            }
            else {
                                
            }
                        
        }
        //尚未進入排程的代碼
        else {
            
            if ([unstart_code_array_his_data indexOfObject:code]==NSNotFound) {
                //避免重復
                //[unstart_code_array_his_data addObject:code]; 
                //將新加入的插入到第一個主要是要讓最近加入的越早取得歷史資料
                [unstart_code_array_his_data insertObject:code atIndex:0];                
                
            } 
            else {
                
                //之前已經有排入 所以將此代碼移到最前面
                [unstart_code_array_his_data removeObject:code];
                [unstart_code_array_his_data insertObject:code atIndex:0];     
                
            }            
            
        }         
    }    
 
    //通知
    {
        //通知 訊息視窗 NOT_BoxInformation_TextField_Top_Show
        {
            NSMutableDictionary *dict = [NSMutableDictionary dictionary];
            [dict setObject:@"顯示進度顯示器" forKey:@"text_string"];
            
            NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
            [nc postNotificationName:NOT_BoxInformation_ProcessIndicator_Show
                              object:self
                            userInfo:dict   ];
            
        }
    
    
    }
}

#pragma mark -
#pragma mark 歷史資料 回補結束

//有真正的回補
-(void)His_Data_Finished:(NSMutableDictionary *)document{
    
    
    
    //1.將回補的歷史數據序列 與最高最低價等新資料存入到物件 並且更新最新的報價
    {
        //a.回補完資料的物件
        Data_Object *obj=[self object_data_arrary_object_from_code_datamodel:[document objectForKey:DB_object_sqlite_basic_code]];
        
              
        //b.設定最新資料給物件
        [obj setHis_data_get_date:[NSDate date]]; //設定取得歷史資料的當下系統時間
        [obj setHis_data_high:[document objectForKey:@"his_data_high"]];
        [obj setHis_data_low:[document objectForKey:@"his_data_low"]];
         
        //c.將今日報價加入到時間序列上
        //表示此物件資料已經有歷史資料檔了=>需要針對此歷史資料檔更新最後的報價
        if ([document objectForKey:@"his_data"]) {
            
            [CommonFunction refresh_quote_last_his_data_update:obj hisdtat_serial:[document objectForKey:@"his_data"] delgeate:self];
            
        }
          
        NSLog(@"His_Data_Finished end=%@",[document objectForKey:DB_object_sqlite_basic_code]);
    }
    
    if (document) {
        //2.通知
        [self note_history_finish:document];
        
        
               
        
    }
    else{
        NSLog(@"無歷史資料內容可以回補");
    
    }
   
    //3.檢查是否有尚未回補完的歷史資料
    
    [self check_His_data_reload_finished];
    
}

//沒有真正的回補 在兩個小時內有回補過歷史資料
-(void)His_Data_Finished_not_reload:(NSMutableDictionary *)document{
    
    //2.通知
    [self note_history_finish:document];
    
    //3.檢查是否已經完全回補完資料
    [self check_His_data_reload_finished];
    
}
//2.通知
-(void)note_history_finish:(NSMutableDictionary *)document{
  
    //通知 APP1_Start_WindowController
    {
        NSMutableDictionary *out_dic=[[NSMutableDictionary alloc] init];
        {
            if (document) {
                 
                //a.
                
                [out_dic setObject:[document objectForKey:DB_object_sqlite_basic_code] forKey:DB_object_sqlite_basic_code];
                
                                 
                
                
                [out_dic setObject:[NSNumber numberWithInt: [unstart_code_array_his_data count]  ] forKey:His_data_reload_ungoing];
                [out_dic setObject:[NSNumber numberWithInt:hisdata_Queue_total_count] forKey:His_data_reload_start_tatal];
                [out_dic setObject:[NSNumber numberWithInt: [queue_his_data operationCount]  ] forKey:His_data_reload_ongoing];                
               
                
                NSLog(@"剩餘歷史資料回補=%ld",[unstart_code_array_his_data count]);
                
            }
            else{
                if ( [unstart_code_array_his_data count] >0 ) {
                    
                    //列印出尚未進入排成的代碼
                    /*
                    for (NSString *c in unstart_code_array_his_data) {
                        NSLog(@"輸出結果是  空白 尚未進入排成的代碼=%@",c);
                    }
                    */
                    
                    [self His_Data_Start:[unstart_code_array_his_data objectAtIndex:0] ];
                    
                    
                }        

                 
            }
           
        }
        
        
        NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
        [nc postNotificationName:NOT_his_reload_APP1_Start_WindowController
                          object:self
                        userInfo: out_dic   ];
        
        [out_dic release];
        
        
        }
    
    //通知 XXsheet_sort
    {
        //通知排序
        // if ( tree_sort_data !=nil && tree_sort_data && document) {
        if ( [[self is_on_TreeSort_DataModel] boolValue]==YES) {
    
            
            NSMutableDictionary *out_dic=[[NSMutableDictionary alloc] init];
            
            //[out_dic setObject:[NSNumber numberWithInt: [queue_his_data operationCount]  ] forKey:@"operationCount"];
            
            [out_dic setObject:[document objectForKey:DB_object_sqlite_basic_code] forKey:DB_object_sqlite_basic_code];
            
          
            
            NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
            [nc postNotificationName:NOT_his_reload_XXsheet_sort
                              object:self
                            userInfo: out_dic   ];
            
            [out_dic release];
        }
        else if ( [[self is_on_output_to_chart_DataModel] boolValue]==YES) {
            
            
            NSMutableDictionary *out_dic=[[NSMutableDictionary alloc] init];
            
            //[out_dic setObject:[NSNumber numberWithInt: [queue_his_data operationCount]  ] forKey:@"operationCount"];
            
            [out_dic setObject:[document objectForKey:DB_object_sqlite_basic_code] forKey:DB_object_sqlite_basic_code];
            
            
            
            NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
            [nc postNotificationName:NOT_his_reload_XXsheet_output
                              object:self
                            userInfo: out_dic   ];
            
            [out_dic release];
        }
        else if ( [[self is_on_output_to_excel_DataModel] boolValue]==YES) {
            
            
            NSMutableDictionary *out_dic=[[NSMutableDictionary alloc] init];
            
            //[out_dic setObject:[NSNumber numberWithInt: [queue_his_data operationCount]  ] forKey:@"operationCount"];
            
            [out_dic setObject:[document objectForKey:DB_object_sqlite_basic_code] forKey:DB_object_sqlite_basic_code];
            
            
            
            NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
            [nc postNotificationName:NOT_his_reload_XXsheet_output
                              object:self
                            userInfo: out_dic   ];
            
            [out_dic release];
        }
        
       
    }

}

//3.檢查是否 需要繼續回補歷史資料
-(void)check_His_data_reload_finished{

   
    if ( [unstart_code_array_his_data count] >0 ) {
        
        //列印出尚未進入排成的代碼
        /*
        for (NSString *c in unstart_code_array_his_data) {
            NSLog(@"尚未進入排成的代碼=%@",c);
        }
        */
        
         
        [self His_Data_Start:[unstart_code_array_his_data objectAtIndex:0] ];
        
        
    }        
        
    int nn;
    nn= [queue_his_data operationCount] ;
    
    if (nn==1) {
        
        NSLog(@"*****表示已經都回補完所有的歷史資料*******");
                 
        //判斷是否需要針對節點進行排序
        if ([[self is_on_TreeSort_DataModel] boolValue]==YES) {
            
            NSLog(@"此次資料回補是為了 樹狀排序");
            NSLog(@"要進行排序=%@", [tree_sort_data objectForKey:key_sort_name]);
            
            //功能步驟：樹狀排序 功能步驟: 6.已經都回補完所有的歷史資料 準備進行節點內部排序
            //資訊流：樹狀排序  7:回補完所有的歷史資料            
            
            
            //1.找出要排序的參考位置
            SourceListItem *select_node=[tree_sort_data objectForKey:key_SourceListItem];
             
            //2.節點內排序進行
            {
                NSLog(@"更新樹狀排序 相關數據" );
                
                //1.將子節點上的個股匯整到上一層的節點
                //[datamodel update_all_tree_folder_tableobject_refresh:0];
                //[datamodel update_all_tree_folder_tableobject_refresh:1];
                
                //2.計算選定節點最下面一列合計數據
                {
                    //欄位表頭資訊
                    NSMutableArray *table_column_data_array=[[self table_column_object_array] table_column_array];
                    
                    //標記：excel輸出的資料欄位
                    NSArray *data_title= nil ;
                    
                    
                    //4.1 計算本節點 最下面一列加總平均數據
                    [[select_node tableobject]  calcuate_table_position_sum_average_all:table_column_data_array barcount:1 data_titles:data_title ];
                    
                    
                    //4.2 計算次節點 最下面一列加總平均數據
                    if ([select_node hasChildren]) {
                        for (SourceListItem *sc in [select_node children]) {
                            [[sc tableobject]  calcuate_table_position_sum_average_all:table_column_data_array barcount:1 data_titles:data_title];
                        }
                    }
                     
                    
                }
                
                //3.更新計算每個節點上要計算的東西 顯示出小框框
                {
                    //a.更新該節點而已
                    [select_node update_TableCalcuate:tree_sort_data];
                    
                    //b.更新該節點的子節點
                    [self tree_folder_to_sum_array:[select_node children]];
                    
                    //c.更新全部的節點
                    //[datamodel update_all_tree_folder_to_sum];
                }
                
                //4.儲存所有樹狀資料
                [self save_all_tree_data:select_node];
                         
            }
            
            
            //3.節點內部進行排序動作
            [select_node sort_TableObjet_Data_Object_Array:tree_sort_data];                         
            
            //4.通知排序完成:此佈告欄貼出後  
            {       
                
                NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
                
                //通知 主程序
                {
                    
                    //a.finish_tree_sort_AppDelgeate  =>主要功用是把sheet關閉
                    //b.finish_tree_sort_APP1_Start_WindowController  =>主要功用是節點儲存
                    
                    [nc postNotificationName:NOT_sheet_tree_sort_finish
                                      object:self
                                    userInfo: tree_sort_data ];
                }                
                
                /*
                //通知 訊息視窗
                {
                    NSLog(@"fffgg");
                    
                    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
                    [dict setObject:@"fff" forKey:@"fgg"];
                    
                    
                    [nc postNotificationName:NOT_BoxInformation_TextField_Top_Show
                                      object:self
                                    userInfo:dict   ];
                
                }
                */
                
                
                
            }
            
           
            
            //5.排序完後進行清理動作 很重要 才能下一次呼叫資料時不會出現要再次排序
            [tree_sort_data release];
             tree_sort_data=nil;
            
            
            
        }
        //判斷此次資料回補是否為了最佳化
        else if ([[self is_on_Optimize_DataModel] boolValue]==YES) {
           
            NSLog(@"此次資料回補是為了 最佳化");
            
            //開始進行最佳化
            [self begin_optimize];
            
            //重設
            [self setIs_on_Optimize_DataModel:[NSNumber numberWithBool:NO]];
        }
        //判斷此次資料回補是否為了輸出資料至走勢圖
        else if ([[self is_on_output_to_chart_DataModel] boolValue]==YES) {
            //資訊流：彙整資料至副圖  3:回補完所有的歷史資料
            
            NSLog(@"此次資料回補是為了 輸出走勢圖=%@",tree_output_data_to_chart);
            /*說明:
             已經有的的資料：
             a.tree_output_data：存放輸出資料的選項所有訊息
             
             
            
            */
            //1.開始進行輸出資料整理
            {
                //0.欄位資料
                NSMutableArray      *table_column_data_array;      //取出報價表上的全部欄位資訊
                NSMutableDictionary *table_column_data_singal;     //要輸出資料的單一欄位資訊
                SourceListItem      *select_node;                  //輸出資料 節點位置
                NSString            *column_identifier;
                {
                    select_node=      [tree_output_data_to_chart objectForKey:key_SourceListItem];//輸出資料 節點位置
                    column_identifier=[tree_output_data_to_chart objectForKey:key_output_name];   //要輸出欄位的標籤
                    
                    table_column_data_singal=[[self table_column_object_array] object_table_column_array_from_column_identfiler:column_identifier];
                   
                    table_column_data_array=[[self table_column_object_array] table_column_array];
                }
                
                
                //1.輸出該節點內的彙整資料
                 NSMutableDictionary *select_node_combine_dic=[[[NSMutableDictionary alloc] init] autorelease]; //選定節點下彙整的資料
               {
                    //到該節點取出資料 重要!!!
                    NSMutableArray *aa=[[select_node tableobject]
                                        output_table_column_all:table_column_data_array
                                        table_column_single:table_column_data_singal
                                        output_data:tree_output_data_to_chart ];
                   
                   if (aa!=nil) {
                       //避免節點內都沒有資料                       
                          [select_node_combine_dic setObject:aa forKey:[select_node title] ];
                   }
                   
                                  
                    
                }
                
                //2.輸出該節點下的子節點內的彙整資料
                NSMutableDictionary *select_node_child_combine_dic=[[[NSMutableDictionary alloc] init] autorelease];//選定節點下的子節點彙整資料
                if ([select_node hasChildren]) {
                   
                    for (SourceListItem *sc in [select_node children]) {
                       
                        //到該節點取出資料 重要!!!
                        NSMutableArray *aa= [[sc tableobject]  output_table_column_all:table_column_data_array
                                               table_column_single:table_column_data_singal
                                                       output_data:tree_output_data_to_chart    ];
                        if (aa!=nil) {
                            //避免節點內都沒有資料
                              [select_node_child_combine_dic setObject:aa forKey:[sc title] ];
                        }
                        
                      
                        
                        
                        
                    }
                }
                
                 
                //3.彙整上面選定節點與子節點的資料
                  NSMutableArray *combine_final_array=[[[NSMutableArray alloc] init] autorelease];//彙整之後最後資料
                {
                    //1.找出期間的開始與結束
                    int start_date=0;
                    int end_date=0;
                    {
                        BOOL start=NO;
                        //選定節點
                        for (NSMutableArray *aaray in [select_node_combine_dic allValues] ) {
                            
                            
                            for (NSMutableDictionary *dic in aaray  ) {
                                int now_date=[[dic objectForKey:TransFormDate] intValue];
                                if (start==NO) {
                                    start=YES;
                                    
                                    start_date=now_date;
                                    end_date=now_date;
                                }
                                if (start_date>= now_date) {
                                    start_date=now_date;
                                }
                                else if (end_date<=now_date) {
                                    end_date=now_date;
                                    
                                }
                                
                            }
                            
                        }
                        //選定節點下的子節點
                        for (NSMutableArray *aaray in [select_node_child_combine_dic allValues] ) {
                            
                            
                            for (NSMutableDictionary *dic in aaray  ) {
                                int now_date=[[dic objectForKey:TransFormDate] intValue];
                                if (start==NO) {
                                    start=YES;
                                    
                                    start_date=now_date;
                                    end_date=now_date;
                                }
                                if (start_date>= now_date) {
                                    start_date=now_date;
                                }
                                else if (end_date<=now_date) {
                                    end_date=now_date;
                                    
                                }
                                
                            }
                            
                        }
                        
                       // NSLog(@"開始日期 =%@ 結束日期=%@",[NSString stringWithFormat:@"%i",start_date],[NSString stringWithFormat:@"%i",end_date] );
                        
                    }
                    //2.製造出暫停陣列
                  
                    {
                        
                        //將數字日期轉成NSDate
                        {
                            NSDate *start_date_ns;
                            NSDate *end_date_ns;
                            
                            NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
                            [dateFormatter setDateFormat:@"yyyyMMdd"];
                            [dateFormatter setTimeZone:   [NSTimeZone timeZoneForSecondsFromGMT:0]];
                            
                            
                            start_date_ns = [dateFormatter dateFromString:[NSString stringWithFormat:@"%i",start_date] ];
                            end_date_ns   = [dateFormatter dateFromString:[NSString stringWithFormat:@"%i",end_date] ];
                            
                            
                            
                            
                            NSLog(@"start_date_ns=%i %@",start_date ,start_date_ns );
                            NSLog(@"end_date_ns=%i %@",end_date,end_date_ns );
                            
                            NSDate *step_date= start_date_ns ;
                            
                            step_date=[step_date dateByAddingTimeInterval:  -24*60*60];
                            do {
                                
                                step_date=[step_date dateByAddingTimeInterval:  24*60*60];
                                {
                                    
                                    
                                    NSMutableDictionary *dic_temp= [[NSMutableDictionary alloc] init] ;
                                    
                                    [dic_temp setObject:  [dateFormatter stringFromDate: step_date] forKey:TransFormDate];
                                    
                                    [combine_final_array addObject:dic_temp];
                                    
                                    [dic_temp release];
                                    
                                    // NSLog(@"step_date=%@ %@", step_date,[dateFormatter stringFromDate: step_date] );
                                }
                            } while ([step_date compare: end_date_ns] !=NSOrderedSame);
                            
                            [dateFormatter release];
                        }
                    }
                    
                    //3.填入資料
                    NSMutableArray *all_title_array=[[[NSMutableArray alloc] init] autorelease];   //標題陣列
                    {
                        NSString *output_calculate_method=[tree_output_data_to_chart objectForKey:key_output_method];
                        
                        //選定節點
                        for (NSMutableArray *aaray in [select_node_combine_dic allValues] ) {
                            
                            NSUInteger ari=[ [select_node_combine_dic allValues] indexOfObject:aaray];
                            NSString *title_key=[[select_node_combine_dic allKeys] objectAtIndex:ari];
                            //製作標題陣列
                            {
                                if ([all_title_array indexOfObject:title_key]==NSNotFound) {
                                    [all_title_array addObject:title_key];
                                }
                                
                                
                            }
                            
                            for (NSMutableDictionary *dic in aaray  ) {
                                
                                //找到新的陣列 相對應的位置
                                NSString *search=[dic objectForKey:TransFormDate];
                                
                                
                                NSUInteger idx = [combine_final_array  indexOfObjectPassingTest:
                                                  ^ BOOL (NSMutableDictionary* obj, NSUInteger idx, BOOL *stop)
                                                  {
                                                      BOOL result = ([ [obj   objectForKey:TransFormDate] isEqualToString:search ]);
                                                      *stop = result;
                                                      return result;
                                                      
                                                  }];
                                
                                
                                if (idx!=NSNotFound) {
                                    //取出暫存陣列的字典
                                    NSMutableDictionary *temp_dic=[combine_final_array objectAtIndex:idx];
                                    [temp_dic setObject:[dic objectForKey:output_calculate_method ] forKey:title_key];
                                    
                                }
                            }
                            
                        }
                        
                        //選定節點下的子節點
                        for (NSMutableArray *aaray in [select_node_child_combine_dic allValues] ) {
                            
                            NSUInteger ari=[ [select_node_child_combine_dic allValues] indexOfObject:aaray];//反推目前陣列對應的key 的位置
                            
                            NSString *title_key=[[select_node_child_combine_dic allKeys] objectAtIndex:ari];//節點標頭
                            //製作標題陣列
                            {
                                if ([all_title_array indexOfObject:title_key]==NSNotFound) {
                                    [all_title_array addObject:title_key];
                                }
                                
                                
                            }
                            for (NSMutableDictionary *dic in aaray  ) {
                                
                                //相對應的位置
                                NSString *search=[dic objectForKey:TransFormDate];
                                
                                
                                NSUInteger idx = [combine_final_array  indexOfObjectPassingTest:
                                                  ^ BOOL (NSMutableDictionary* obj, NSUInteger idx, BOOL *stop)
                                                  {
                                                      BOOL result = ([ [obj   objectForKey:TransFormDate] isEqualToString:search ]);
                                                      *stop = result;
                                                      return result;
                                                      
                                                  }];
                                
                                
                                if (idx!=NSNotFound) {
                                    //取出暫存陣列的字典
                                    NSMutableDictionary *temp_dic=[combine_final_array objectAtIndex:idx];
                                    [temp_dic setObject:[dic objectForKey:output_calculate_method ] forKey:title_key];
                                    
                                }
                            }
                            
                        }
                    }
                    
                    NSLog(@"all_title_array=%@",all_title_array);
                    
                    //4.填入空白資料
                    NSMutableDictionary *last_dic= [[NSMutableDictionary alloc] init] ;
                    {
                        
                        //1.建構一個存放前一期的字典
                        for ( NSString *title in all_title_array) {
                            [last_dic setObject:[NSNumber numberWithInt:0] forKey:title];
                            
                        }
                        NSLog(@"存放前一期的字典=%@", last_dic );
                        
                        
                        //2.開始填充空白位置
                        for (NSMutableDictionary *sdic in combine_final_array) {
                            //針對每一筆字典取出對應應該有的資料
                            NSMutableDictionary *new_last_dic=[last_dic mutableCopy];
                            for (NSString *keyss in last_dic) {
                                if ([sdic objectForKey:keyss]) {
                                    
                                    //表示該時間點有資料 更新最後一筆資料
                                    [new_last_dic setObject:[sdic objectForKey:keyss]  forKey:keyss  ];
                                    
                                }
                                else{
                                    //表示該時間沒有此資料 將最後一筆資料填入此位置
                                    [sdic setObject:[last_dic objectForKey:keyss] forKey:keyss];
                                    
                                }
                                
                                
                                
                            }
                            [last_dic release];
                            last_dic=[new_last_dic mutableCopy];
                            [new_last_dic release];
                        }
                        
                    }
                    [last_dic release];
                    
                    //NSLog(@"合成完成的整合陣列數據=%@",combine_final_array);
                }
                
                //4.依照不同目的將資料彙整傳出去
                {
                    
                    //資訊流：彙整資料至副圖  6:依照不同目的將資料彙整傳出去
                    
                    if ([[tree_output_data_to_chart objectForKey:key_output_data ] isEqualToString:@"output_to_chart" ]) {
                        
                        
                                              
                        //通知走勢圖繪圖
                        {
                            NSMutableDictionary *dict = [NSMutableDictionary dictionary];
                            
                            //選單選項
                            [dict setObject:tree_output_data_to_chart          forKey:OutPut_tree_output_data];
                            
                            //彙整結果
                            [dict setObject:combine_final_array       forKey:OutPut_combine_final_array];
                            
                            NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
                            [nc postNotificationName:NOT_output_chart
                                              object:self
                                            userInfo: dict   ];
                        
                        }
                        
                        
                    }
                    else if ([[tree_output_data_to_chart objectForKey:key_output_data ] isEqualToString:@"output_to_file" ]) {
                        NSLog(@"輸出到檔案");
                        
                    }
                }
                
            }
            
            //2.通知排序完成:此佈告欄貼出後 會通知兩個
            {
                //a.finish_tree_sort_AppDelgeate  =>主要功用是把sheet關閉
                //b.finish_tree_sort_APP1_Start_WindowController  =>主要功用是節點儲存
                
                NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
                [nc postNotificationName:NOT_sheet_tree_output_Chart_finish
                                  object:self
                                userInfo: tree_output_data_to_chart ];
            }
             
            
            //重設
            [self setIs_on_Optimize_DataModel:[NSNumber numberWithBool:NO]];
        }
        //判斷此次資料回補是否為了輸出資料至excel
        else if ([[self is_on_output_to_excel_DataModel] boolValue]==YES){
          //資訊流：彙整資料至EXCEL  4:回補完所有的歷史資料            
            
            NSLog(@"此次資料回補是為了 輸出excel=%@",tree_output_data_to_excel);
            
            //1.計算節點內的最後一筆表格總計與平均資料
            {
                //1.找出要排序的參考位置
                SourceListItem *select_node=[tree_output_data_to_excel objectForKey:key_SourceListItem];
                
                //2.計算選定節點最下面一列合計數據
                {
                    //欄位表頭資訊
                    NSMutableArray *table_column_data_array=[[self table_column_object_array] table_column_array];
                    
                  
                    
                    //標記：excel輸出的資料欄位
                    NSArray *data_title=[tree_output_data_to_excel objectForKey:key_output_Excel_column_array] ;
                    
                    //標記：修改總和與平均往前推的期數                    
                    int bar_count=[[tree_output_data_to_excel objectForKey:key_output_Excel_row_count] intValue];                    
                    
                    
                    
                    //4.1 計算本節點 最下面一列加總平均數據
                    [[select_node tableobject]  calcuate_table_position_sum_average_all:table_column_data_array barcount:bar_count data_titles:data_title];
                    
                    
                    //4.2 計算次節點 最下面一列加總平均數據
                    if ([select_node hasChildren]) {
                        for (SourceListItem *sc in [select_node children]) {
                            [[sc tableobject]  calcuate_table_position_sum_average_all:table_column_data_array barcount:bar_count data_titles:data_title];
                        }
                    }
                    
                    //[self tree_folder_to_sum_array:[select_node children]];
                    
                }             
            }
           
            
            //2.通知排序完成:此佈告欄貼出後 會通知兩個
            {
                //a.finish_tree_sort_AppDelgeate  =>主要功用是把sheet關閉
                //b.finish_tree_sort_APP1_Start_WindowController  =>主要功用是節點儲存
                
                NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
                [nc postNotificationName:NOT_sheet_tree_output_Excel_finish
                                  object:self
                                userInfo: tree_output_data_to_excel ];
            }

            
            
            
        }
        
        //一般回補
        else{
           NSLog(@"此次資料回補是一般回補");
           
            //通知 訊息視窗 NOT_BoxInformation_TextField_Top_Show
            {
                NSMutableDictionary *dict = [NSMutableDictionary dictionary];
                [dict setObject:NSLocalizedString(@"finish_reload_data", "finish_reload_data") forKey:@"text_string"];
                
                NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
                [nc postNotificationName:NOT_BoxInformation_TextField_Top_Show
                                  object:self
                                userInfo:dict   ];
                
            }

            
            
        }
        
       
        
    }
    else {
          //NSLog(@"還在執行的歷史資料程序數目 =%i",nn  );
    }
    
}


// 歷史資料執行緒 開始數量
-(void)set_hisdata_Queue_total_count{

    hisdata_Queue_total_count=[queue_his_data operationCount ]+[unstart_code_array_his_data count];
}


#pragma mark -
#pragma mark 開始進行最佳化
-(void)begin_optimize{
   
    NSLog(@"####開始進行最佳化 節點=%@", [Para_SLT_optimize title] );
    
    //最佳化執行緒最大使用量
    {
        //取出最佳化資料字典
        NSMutableDictionary *para_dic;
        NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
        NSMutableDictionary *para_dic_par=[prefs  objectForKey:Para_Optimize_Dic];
     
        
        
        {
            para_dic=[para_dic_par  objectForKey:optimize_method];
            NSLog(@"最佳化參數字典=%@",para_dic);
            int que_number=[[para_dic objectForKey:Para_Optimize_que_number] intValue];
            [queue_optimize_para setMaxConcurrentOperationCount:que_number];            
        }
     
    }
    
  
    //進入循環
    for (Data_Object *dbb in [[Para_SLT_optimize tableobject] data_array_object]) {
        
        NSString *code=[[dbb table_data] objectForKey:DB_object_sqlite_basic_code];
        
        
        //NSLog(@"!!!!!進入 個股股票資料進行最佳化執行階段=%@ method=%@",code,optimize_method);
        
       // [dbb run_optimize:optimize_method ];
         
        Optimize_Para *plo = [[Optimize_Para alloc] init_With_Data_Object:dbb optimize_method:optimize_method] ;
        
        //設定執行緒委託
        [plo setDelgeate:self];
        
        //加入到執行工作序上
        [queue_optimize_para addOperation:plo];
        
        [plo release];
                 
       
        
        NSLog(@"!!!!!完成 個股股票資料進行最佳化執行階段=%@ method=%@",code,optimize_method);
        
                
        
    }
    
    
    
    NSLog(@"#####完成最佳化 節點=%@", [Para_SLT_optimize title] );
    
}

#pragma mark -
#pragma mark Yahoo-Google轉換
-(NSString *)input_YahooCode_return_GoogleCode:(NSString*)YahooCode{
    NSString *google_code=nil;
    
    //是否要透過資料庫取出資料
    NSUInteger idx = [code_array_Yahoo_Google  indexOfObjectPassingTest:
                      ^ BOOL (NSMutableDictionary* obj, NSUInteger idx, BOOL *stop)
                      {
                          BOOL result = ([ [obj   objectForKey:Code_Yahoo] isEqualToString:YahooCode ]);
                          *stop = result;
                          return result;
                          
                      }];
    
    if (idx==NSNotFound) {
        //1.資料庫物件宣告
        FMDatabase *db;
        //FMResultSet *rs;
        
        //2.開啓資料庫
        NSString *databasePathnsame=[File_Name_Path sqlite_database_path_name:YES];
        db=[FMDatabase databaseWithPath:databasePathnsame];
        //記住一定要 開啓資料庫 [db open]
        
        if (![db open]) {
            
            return nil;
            
        }
        else{
            
            
            //解析出要放在sqlite表上的表頭名稱
            NSString *sqlite_table;
            {
                
                NSString *yahoo_sqlite_exchange;
                if ([YahooCode hasPrefix:@"^"]) {
                    
                    //指數
                    yahoo_sqlite_exchange=@"INDEX";
                    
                }
                else{
                    
                    //股票
                    NSArray *para=[YahooCode componentsSeparatedByString:@"."];
                    if ([para count]==1) {
                        yahoo_sqlite_exchange=@"US";
                    }
                    else if ([para count]==2){
                        yahoo_sqlite_exchange=[para objectAtIndex:1];
                    }
                    else{
                        
                        //關閉資料庫
                        [db close];
                        
                        return nil;
                    }
                    
                }
                
                sqlite_table=[NSString stringWithFormat:@"Code_Convert_%@",yahoo_sqlite_exchange];
                //NSLog(@"yahoo_code=%@, sqlite_table=%@",YahooCode ,sqlite_table );
                
            }
            
            
            
            NSString *sels=[NSString stringWithFormat:@"SELECT * FROM %@ WHERE code_yahoo='%@'",sqlite_table,YahooCode];
            
            
            FMResultSet *rs=[db executeQuery:sels];
            
            while ([rs next]) {
                
                google_code= [rs stringForColumn:@"code_google"]  ;
                
                
            }
            
            //關閉資料庫
            [db close];
        } 
        
        //NSLog(@"透過sqlite取出資料=%@",google_code);
        
    }
    else{
    
        NSMutableDictionary *dic=[code_array_Yahoo_Google objectAtIndex:idx];
       
        google_code=[dic objectForKey:Code_Google];
        //NSLog(@"不是 透過sqlite取出資料=%@",google_code);
    }
    
       
    
    return google_code;
}

#pragma mark 執行報價回報
//資訊流：樹狀排序  6:回補報價資料
//功能步驟：樹狀排序 功能步驟: 5.回補報價資料
-(void)Quote_Start:(NSArray *)code_array{
    
    //1.先將代碼陣列 分隔
    NSMutableArray *code_array_YGB;   //存放代碼陣列的陣列 Yahoo Google Bloomberg
    NSMutableArray *code_array_Google=[[[NSMutableArray alloc] init] autorelease];//存放代碼陣列的陣列 在MultiServer中特別針對Google部份額外
    {
        //如果是多伺服器的選項則資料陣列拆成兩組code_array_YGB 與code_array_Google
        if ([datasource isEqualToString:id_MultiServer_GY]){
            
            //分別yahoo 與google的代碼出來
            NSMutableArray *yahoo_code_array=[[[NSMutableArray alloc] init]autorelease];
            NSMutableArray *google_code_array=[[[NSMutableArray alloc] init]autorelease];
            
            //1.分離出有哪些股票可以使用google 報價資料 因為是即時報價關係
            NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];            
            for (NSString *yahoo_code in code_array  ) {                 
                
                //判斷是否可以使用即時資料
                if ([[prefs objectForKey:Real_Time_Subscription_isExpire] isEqualToNumber:[NSNumber numberWithBool:YES]] ) {
                    
                    //到期：使用yahoo
                    [yahoo_code_array addObject:yahoo_code];
                    
                     
                }
                else{
                    //尚未到期：所以為即時資料狀態 所以再次判斷是要用google或是yahoo
                    
                    //從sqlite資料庫找 如果有google代碼與yahoo代碼資料就將此股票從google下載報價資料
                    NSString *google_code=[self input_YahooCode_return_GoogleCode:yahoo_code];
                    
                    if (google_code) {
                        
                        [google_code_array addObject:google_code];
                        
                        //建立陣列
                        {
                            
                            //檢查使否已經有過此資料
                            NSUInteger idx = [code_array_Yahoo_Google  indexOfObjectPassingTest:
                                              ^ BOOL (NSMutableDictionary* obj, NSUInteger idx, BOOL *stop)
                                              {
                                                  BOOL result = ([ [obj   objectForKey:Code_Google] isEqualToString:google_code ]);
                                                  *stop = result;
                                                  return result;
                                                  
                                              }];
                            
                            //如果字點陣列內沒有該筆資料才要加入
                            if (idx==NSNotFound) {
                                
                                NSMutableDictionary *dicc=[[NSMutableDictionary alloc] init];
                                [dicc setObject:yahoo_code forKey:Code_Yahoo];
                                [dicc setObject:google_code forKey:Code_Google];
                                
                                [code_array_Yahoo_Google addObject:dicc];
                                [dicc release];
                                
                            }
                            
                            
                        }
                        
                        
                    }
                    else{
                        [yahoo_code_array addObject:yahoo_code];
                    }
                    
                     
                }                                
            }
            
            
            //2.分別建立兩組陣列資料
            
            code_array_YGB=[[NSMutableArray alloc] init]; //因為會在最後面release 所以在此處不release
            //code_array_Google=[[[NSMutableArray alloc] init] autorelease];
                       
            int code_max_every_array=Max_Qote_Every_Load_url;
            
            //yahoo 代碼陣列：code_array_YGB
            {
                NSMutableArray *code_YGB; //單一存放代碼
                code_YGB=[[[NSMutableArray alloc] init] autorelease];
                int add_count_yahoo=0;
                
                for (int i=0; i<[yahoo_code_array count]; i++) {
                    
                    if (add_count_yahoo<code_max_every_array) {
                        
                        [code_YGB addObject:[yahoo_code_array objectAtIndex:i]];
                        add_count_yahoo=add_count_yahoo+1;
                        
                    }
                    else {
                        [code_array_YGB addObject:code_YGB];//加入代碼陣列
                        
                        
                        //歸0 重新再來一次
                        add_count_yahoo=0;
                        code_YGB=[[[NSMutableArray alloc] init] autorelease];
                        
                        
                        [code_YGB addObject:[yahoo_code_array objectAtIndex:i]];
                        add_count_yahoo=add_count_yahoo+1;
                        
                    }
                    
                    
                    
                }
                //剩餘
                [code_array_YGB addObject:code_YGB];//加入代碼陣列
                
            }
           
            //google 代碼陣列：code_array_Google
            {
                NSMutableArray *code_Google; //單一存放代碼
                code_Google=[[[NSMutableArray alloc] init] autorelease];
                
                int add_count_google=0;
                
                for (int i=0; i<[google_code_array count]; i++) {
                    
                    if (add_count_google<code_max_every_array) {
                        
                        [code_Google addObject:[google_code_array objectAtIndex:i]];
                        add_count_google=add_count_google+1;
                        
                    }
                    else {
                        [code_array_Google addObject:code_Google];//加入代碼陣列
                        
                        
                        //歸0 重新再來一次
                        add_count_google=0;
                        code_Google=[[[NSMutableArray alloc] init] autorelease];
                        
                        
                        [code_Google addObject:[google_code_array objectAtIndex:i]];
                        add_count_google=add_count_google+1;
                        
                    }
                    
                    
                    
                }
                //剩餘
                [code_array_Google addObject:code_Google];//加入代碼陣列
                
            }
            
            //最後得出來的分割陣列
            //NSLog(@"code_array_YGB=%@",code_array_YGB);
            //NSLog(@"code_array_Google=%@",code_array_Google);
            //NSLog(@"code_array_Yahoo_Google=%@",code_array_Yahoo_Google);
            
             
        }
        //其他非MultiServer資料源
        else{
            
            NSMutableArray *code_a; //單一存放代碼
            
            //建立記憶體
            code_array_YGB=[[NSMutableArray alloc] init];
            code_a=[[NSMutableArray alloc] init];
            
            int code_max_every_array=Max_Qote_Every_Load_url;
            int add_count=0;
            
            for (int i=0; i<[code_array count]; i++) {
                
                if (add_count<code_max_every_array) {
                    
                    [code_a addObject:[code_array objectAtIndex:i]];
                    add_count=add_count+1;
                    
                }
                else {
                    [code_array_YGB addObject:code_a];//加入代碼陣列
                    [code_a release];
                    
                    //歸0 重新再來一次
                    add_count=0;
                    code_a=[[NSMutableArray alloc] init];
                    
                    
                    [code_a addObject:[code_array objectAtIndex:i]];
                    add_count=add_count+1;
                    
                }
                
                
                
            }
            
            //剩餘
            [code_array_YGB addObject:code_a];//加入代碼陣列
            [code_a release];
        
        }           
    }    
    
    //2.依照不同資料來源啓動執行緒
    if ([datasource isEqualToString:id_Yahoo_WEB]) {
        //將針對每個代碼陣列陣列
        
         quote_Queue_total_count=[code_array_YGB count];//起始回補報價執行緒數量        
        for (NSArray * cc in code_array_YGB ) {
            //將單一代碼陣列轉成連續字串
            if ([cc count]>0) {
                
                NSString *multi_code_string;
                multi_code_string=[NSString stringWithFormat:@"%@+",  [cc objectAtIndex:0]  ];
                
                if ([cc count]>1) {
                    //如果超過一個代碼    
                    for (int i=1; i<[cc count]; i++) {
                        
                        multi_code_string=[multi_code_string stringByAppendingFormat:@"%@+",[cc objectAtIndex:i]];
                        
                    }
                    
                }
                //加入此段是因為 yahoo的指數代碼^開頭 先將此符號轉為url看懂的%5E
                multi_code_string=[multi_code_string stringByReplacingOccurrencesOfString:@"^" withString:@"%5E"];
                
                //將代碼字串加入到ＵＲＬ
                NSString *urls_bloomberg= [NSString stringWithFormat: @"http://download.finance.yahoo.com/d/quotes.csv?s=%@&f=sol1hgd1t1c1p2vrj1kjdye7&e=.csv",multi_code_string]  ;      
                //NSLog(@"codes=%@",multi_code_string);
                 
                
                //注意事項： %% 
                
                //轉成 NSURL
                NSURL *url = [NSURL URLWithString:urls_bloomberg];  
                
                //[queue cancelAllOperations];
                
                //建立執行緒事件
                Yahoo_Quote_WEB *plo = [[Yahoo_Quote_WEB alloc] init_WithURL:url] ;
                
                //設定執行緒委託
                [plo setDelgeate:self];
                
                //加入到執行工作序上
                [queue_quote setMaxConcurrentOperationCount:Max_OperationQueue_yahooWeb];
                [queue_quote addOperation:plo];
                [plo release];
                
                               
                    
                                
                // NSLog(@"operationCount=%ld",[queue operationCount] );   
            }
            
        }        
        
        /*
         
         NSURL *url = [NSURL URLWithString:@"http://finance.iphone.mobile.yahoo.com/3fc7/quote/symbol/2330.TW,AAPL,2498.TW?view=detail&format=json"];         
         
         //建立執行緒事件
         
         Yahoo_Quote_Mobile *plo = [[Yahoo_Quote_Mobile alloc] init_WithURL:url] ;
         
         
         //設定執行緒委託
         [plo setDelgeate:self];
         
         //加入到執行工作序上
         
         [queue_quote addOperation:plo];
         
         [plo release]; 
         */        
        
    }
    else if ([datasource isEqualToString:id_Yahoo_Mobile]) {
        
        
        //將針對每個代碼陣列陣列
         quote_Queue_total_count=[code_array_YGB count];//起始回補報價執行緒數量        
        
        for (NSArray * cc in code_array_YGB ) {
            //將單一代碼陣列轉成連續字串
            if ([cc count]>0) {
                
                NSString *multi_code_string;
                multi_code_string=[NSString stringWithFormat:@"%@,",  [cc objectAtIndex:0]  ];
              
                if ([cc count]>1) {
                    //如果超過一個代碼    
                    for (int i=1; i<[cc count]; i++) {
                        
                        multi_code_string=[multi_code_string stringByAppendingFormat:@"%@,",[cc objectAtIndex:i]];
                        
                    }
                    
                }
                //加入此段是因為 yahoo的指數代碼^開頭 先將此符號轉為url看懂的%5E
                multi_code_string=[multi_code_string stringByReplacingOccurrencesOfString:@"^" withString:@"%5E"];
                
                //將代碼字串加入到ＵＲＬ
                NSString *urls_bloomberg= [NSString stringWithFormat: @"http://finance.iphone.mobile.yahoo.com/3fc7/quote/symbol/%@?view=detail&format=json",multi_code_string]  ;      
                //NSLog(@"codes=%@",multi_code_string);
                //NSLog(@"urls_bloomberg=%@",urls_bloomberg);
                
                //注意事項： %% 
                
                //轉成 NSURL
                NSURL *url = [NSURL URLWithString:urls_bloomberg];  
                
                //建立執行緒事件
                Yahoo_Quote_Mobile *plo = [[Yahoo_Quote_Mobile alloc] init_WithURL:url] ;
                
                //設定執行緒委託
                [plo setDelgeate:self];
                
                //加入到執行工作序上
                [queue_quote setMaxConcurrentOperationCount:Max_OperationQueue_yahooMobile];
                [queue_quote addOperation:plo];
                [plo release];
                 
                    
                                
                // NSLog(@"operationCount=%ld",[queue operationCount] );   
            }
            
        }        
        
        /*
        
        NSURL *url = [NSURL URLWithString:@"http://finance.iphone.mobile.yahoo.com/3fc7/quote/symbol/2330.TW,AAPL,2498.TW?view=detail&format=json"];         
        
        //建立執行緒事件
       
        Yahoo_Quote_Mobile *plo = [[Yahoo_Quote_Mobile alloc] init_WithURL:url] ;
        
        
        //設定執行緒委託
        [plo setDelgeate:self];
         
        //加入到執行工作序上
               
        [queue_quote addOperation:plo];
               
        [plo release]; 
           */    
        
    }
    else if ([datasource isEqualToString:id_MultiServer_GY]) {
         
        //兩個數量相加
        quote_Queue_total_count=[code_array_YGB count]+[code_array_Google count];//起始回補報價執行緒數量
       
        //Yahoo
        for (NSArray * cc in code_array_YGB ) {
           
            //將單一代碼陣列轉成連續字串
            if ([cc count]>0) {
                
                NSString *multi_code_string;
                multi_code_string=[NSString stringWithFormat:@"%@+",  [cc objectAtIndex:0]  ];
                
                if ([cc count]>1) {
                    //如果超過一個代碼
                    for (int i=1; i<[cc count]; i++) {
                        
                        multi_code_string=[multi_code_string stringByAppendingFormat:@"%@+",[cc objectAtIndex:i]];
                        
                    }
                    
                }
                //加入此段是因為 yahoo的指數代碼^開頭 先將此符號轉為url看懂的%5E
                multi_code_string=[multi_code_string stringByReplacingOccurrencesOfString:@"^" withString:@"%5E"];
                
                //將代碼字串加入到ＵＲＬ
                NSString *urls_bloomberg= [NSString stringWithFormat: @"http://download.finance.yahoo.com/d/quotes.csv?s=%@&f=sol1hgd1t1c1p2vrj1kjdye7&e=.csv",multi_code_string]  ;
                //NSLog(@"codes=%@",multi_code_string);
                
                
                //注意事項： %%
                
                //轉成 NSURL
                NSURL *url = [NSURL URLWithString:urls_bloomberg];
                
                //[queue cancelAllOperations];
                
                //建立執行緒事件
                
                Multi_Server_GY_Quote *plo = [[Multi_Server_GY_Quote alloc] init_WithURL:url] ;                 
                
                //設定執行緒委託
                [plo setDelgeate:self];
                
                //加入到執行工作序上
                [queue_quote setMaxConcurrentOperationCount:Max_OperationQueue_yahooWeb];
                [queue_quote addOperation:plo];
                [plo release];
                
                
                
                
                // NSLog(@"operationCount=%ld",[queue operationCount] );
            }
            
        }
        
        //Google
        for (NSArray * cc in code_array_Google ) {
            //將單一代碼陣列轉成連續字串
            if ([cc count]>0) {
                
                NSString *multi_code_string;
                multi_code_string=[NSString stringWithFormat:@"%@,",  [cc objectAtIndex:0]  ];
                
                if ([cc count]>1) {
                    //如果超過一個代碼
                    for (int i=1; i<[cc count]; i++) {
                        
                        multi_code_string=[multi_code_string stringByAppendingFormat:@"%@,",[cc objectAtIndex:i]];
                        
                    }
                    
                }
                //加入此段是因為 yahoo的指數代碼^開頭 先將此符號轉為url看懂的%5E
                multi_code_string=[multi_code_string stringByReplacingOccurrencesOfString:@"^" withString:@"%5E"];
                
                //將代碼字串加入到ＵＲＬ
                NSString *urls_bloomberg= [NSString stringWithFormat: @"http://www.google.com/finance/info?infotype=infoquoteall&q=%@",multi_code_string]  ;
                 //NSLog(@"codes=%@",multi_code_string);
                 NSLog(@"urls_google=%@",urls_bloomberg);
                               
                //注意事項： %%
                
                //轉成 NSURL
                NSURL *url = [NSURL URLWithString:urls_bloomberg];
                
                //建立執行緒事件
                Multi_Server_Google_Quote *plo = [[Multi_Server_Google_Quote alloc] init_WithURL:url _Yahoo_data_quote_array:code_array_Yahoo_Google] ;
                
                
                
                //設定執行緒委託
                [plo setDelgeate:self];
                
                //加入到執行工作序上
                [queue_quote setMaxConcurrentOperationCount:Max_OperationQueue_google];
                [queue_quote addOperation:plo];
                [plo release];
                
                
                
                
                
                
                
                // NSLog(@"operationCount=%ld",[queue operationCount] );
            }
            
        }
        
        
    }
    else if ([datasource isEqualToString:id_Google]) {
        //將針對每個代碼陣列陣列
         quote_Queue_total_count=[code_array_YGB count];//起始回補報價執行緒數量        
        for (NSArray * cc in code_array_YGB ) {
            //將單一代碼陣列轉成連續字串
            if ([cc count]>0) {
                
                NSString *multi_code_string;
                multi_code_string=[NSString stringWithFormat:@"%@,",  [cc objectAtIndex:0]  ];
                
                if ([cc count]>1) {
                    //如果超過一個代碼    
                    for (int i=1; i<[cc count]; i++) {
                        
                        multi_code_string=[multi_code_string stringByAppendingFormat:@"%@,",[cc objectAtIndex:i]];
                        
                    }
                    
                }
                //加入此段是因為 yahoo的指數代碼^開頭 先將此符號轉為url看懂的%5E
                multi_code_string=[multi_code_string stringByReplacingOccurrencesOfString:@"^" withString:@"%5E"];
                
                //將代碼字串加入到ＵＲＬ
                NSString *urls_bloomberg= [NSString stringWithFormat: @"http://www.google.com/finance/info?infotype=infoquoteall&q=%@",multi_code_string]  ;      
                //NSLog(@"codes=%@",multi_code_string);
                // NSLog(@"urls_bloomberg=%@",urls_bloomberg);
                
                //注意事項： %% 
                
                //轉成 NSURL
                NSURL *url = [NSURL URLWithString:urls_bloomberg];  
                
                //建立執行緒事件
                Google_Quote *plo = [[Google_Quote alloc] init_WithURL:url] ;
                
                //設定執行緒委託
                [plo setDelgeate:self];
                
                //加入到執行工作序上
                [queue_quote setMaxConcurrentOperationCount:Max_OperationQueue_google];
                [queue_quote addOperation:plo];
                [plo release];
                 
                    
                                  
                    
                    
                
                
                // NSLog(@"operationCount=%ld",[queue operationCount] );   
            }
            
        }         
        
    }
    else if ([datasource isEqualToString:id_Bloomberg]) {
        
        
        //將針對每個代碼陣列陣列
        quote_Queue_total_count=[code_array_YGB count];//起始回補報價執行緒數量
       
        for (NSArray * cc in code_array_YGB ) {
            //將單一代碼陣列轉成連續字串
            if ([cc count]>0) {
                
                NSString *multi_code_string;
                multi_code_string=[NSString stringWithFormat:@"%@,", [cc objectAtIndex:0]];
                
                if ([cc count]>1) {
                    //如果超過一個代碼    
                    for (int i=1; i<[cc count]; i++) {
                        
                        multi_code_string=[multi_code_string stringByAppendingFormat:@"%@,",[cc objectAtIndex:i]];
                        
                    }
                    
                }
                //將代碼字串加入到ＵＲＬ
                NSString *urls_bloomberg= [NSString stringWithFormat: @"http://m.bloomberg.com/iphone/apps/wds/SecurityData.asp?Securities=%@&Outfields=WBTKR,DS192,DS520,PR005,PR051,PR052,PR006,PR007,PR008,PR013,DS318,HS001,HS003,HS002,HS004,UTIME,RT012,RR900,RR902&bbipver=1.0.9,17243a4e72c7eadd0e9823cd887f97212efa43fa,iPad,iPhone%%20OS,5.0.1,zh_TW,zh-Hant",multi_code_string]  ;      
                //注意事項： %% 
                
                //轉成 NSURL
                NSURL *url = [NSURL URLWithString:urls_bloomberg];
                
                
                
                
                //[queue cancelAllOperations];
                
                //建立執行緒事件
                XML_Bloomberg_Quote *plo = [[XML_Bloomberg_Quote alloc] init_WithURL:url] ;
                
                //設定執行緒委託
                [plo setDelgeate:self];
                
                //加入到執行工作序上
                [queue_quote setMaxConcurrentOperationCount:Max_OperationQueue_bloomberg];
                [queue_quote addOperation:plo];
                [plo release];
                    
                               
                // NSLog(@"operationCount=%ld",[queue operationCount] );   
            }
            
        }
        
    }
    
    //3.通知
    {
        //通知開始報價
        {
            NSMutableDictionary *dict = [NSMutableDictionary dictionary];
            
           
            //[dict setObject:[NSNumber numberWithInt: [queue_quote operationCount]] forKey:@"operationCount"];
            
            NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
            [nc postNotificationName:NOT_quote_begin
                              object:self
                            userInfo: dict   ];
        }
        
        //通知 XXsheet_sort
        {
            if ( [[self is_on_TreeSort_DataModel] boolValue]==YES) {
            
                 NSLog(@"!!!樹狀排序通知開始");                
                
                
                NSMutableDictionary *out_dic=[[NSMutableDictionary alloc] init];
                
                
                [out_dic setObject:code_array  forKey:@"code_array"];
                
                
                NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
                [nc postNotificationName:NOT_quote_begin_XXsheet_sort
                                  object:self
                                userInfo: out_dic   ];
                
                [out_dic release];
            }
            else  if ( [[self is_on_output_to_chart_DataModel] boolValue]==YES) {
                
                NSLog(@"!!!chart輸出通知開始");
                
                
                NSMutableDictionary *out_dic=[[NSMutableDictionary alloc] init];
                
                
                [out_dic setObject:code_array  forKey:@"code_array"];
                
                
                NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
                [nc postNotificationName:NOT_quote_begin_XXsheet_output
                                  object:self
                                userInfo: out_dic   ];
                
                [out_dic release];
            }
            else  if ( [[self is_on_output_to_excel_DataModel] boolValue]==YES) {
                
                NSLog(@"!!!excel輸出通知開始");
                
                
                NSMutableDictionary *out_dic=[[NSMutableDictionary alloc] init];
                
                
                [out_dic setObject:code_array  forKey:@"code_array"];
                
                
                NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
                [nc postNotificationName:NOT_quote_begin_XXsheet_output
                                  object:self
                                userInfo: out_dic   ];
                
                [out_dic release];
            }
            
            
        } 
    
    } 
    
    [code_array_YGB release];
       
    
}

//執行緒工作結束後
//標記：建立執行緒 5.接受到執行緒資料計算結束 將新資料更新
- (void)Quote_Finished:(NSArray *)document;
{
    //document 存放的是執行緒完工後的資料就放在裡面
         
     
    
    //標記：建立執行緒 6.接受到執行緒資料計算結束 將新資料更新 後張貼佈告欄 給有觀察者
    
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
	 
    //[dict setObject:[NSNumber numberWithInt: [queue_quote operationCount]] forKey:@"operationCount"];
    [dict setObject:[NSNumber numberWithInt: quote_Queue_total_count] forKey:Quote_OperationQueue_total];
    [dict setObject:[NSNumber numberWithInt: [queue_quote operationCount]] forKey:Quote_OperationQueue_ungoing];
    
    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
    [nc postNotificationName:NOT_quote_reload
					  object:self
					userInfo: dict   ];    
    
    
    
    NSLog(@"報價 執行緒剩下數目=%ld", [queue_quote operationCount]  );  
   
    
}
 

#pragma mark -
#pragma mark 資料庫有哪些報價欄位
 
+(NSMutableArray*)Table_columns_array:(NSString *)datasourcea{
    //標記：增加表格欄位 3.add確定    
   
    
    RLTableColumnHeader *dm;
    
    dm= [[[RLTableColumnHeader alloc] init_datasource:datasourcea] autorelease]  ;
    
    NSMutableArray * tablecolumn_array;   
    tablecolumn_array=[[[NSMutableArray alloc] init] autorelease];
    
    
    for (NSMutableDictionary *tdic in [dm table_column_array]) {
        [tablecolumn_array addObject:[tdic objectForKey:Table_Column_Key]];
    }
     
    return  [dm table_column_array] ;
    
    //return tablecolumn_array;
     
}
#pragma mark -
#pragma mark 資料庫有哪些歷史資料計算方法

+(NSMutableArray*)RLChartMenuItem_array:(NSString *)datasourcea{
          
    RLChartMenuItem *dm;
    dm= [[[RLChartMenuItem alloc] init_datasource:datasourcea] autorelease]  ;
    
    /*
    NSMutableArray * RLChartMenuItem_array;   
    RLChartMenuItem_array=[[[NSMutableArray alloc] init] autorelease];
    
    
    for (NSMutableDictionary *tdic in [dm RLChartMenuItem_array]) {
     [RLChartMenuItem_array addObject:[tdic objectForKey:Table_Column_hisdata_calculate_method]];
    }
    */
         
    return  [dm RLChartMenuItem_array_A] ;
         
}
 


-(void)reset_history_memory{
   
    NSLog(@"reset_history_memory");
    
     
}

#pragma mark -
#pragma mark 重新計算所有指標與訊號

-(void)re_calculate_all_history_object_indicator_signal{
    NSLog(@"re_calculate_all_history_object_indicator_signal");
   
    for (Data_Object * ob in data_object_arrary) {
        [ob re_calculate_history_indicator_signal];
    }
        
}




#pragma mark -
#pragma mark 將NSdate 轉成 yyyyMMdd
-(int)nsdate_convert_to_yyyymmdd:(NSDate *)dates timezone:(NSString *)ts{
    NSDate *datetime_dt=dates;
    
    
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    dateFormatter.dateFormat = @"yyyyMMdd";
    
    
    // NSTimeZone *gmt = [NSTimeZone timeZoneWithName:[datamodel symbol_convert_timeZone:[[ob table_data] objectForKey:DB_object_sqlite_basic_code]]];
    NSTimeZone *gmt = [NSTimeZone timeZoneWithName:  ts ];
    
    [dateFormatter setTimeZone:gmt];
    
    NSString *timeStamp = [dateFormatter stringFromDate:datetime_dt];
    [dateFormatter release];                   
    
    return [timeStamp intValue];

}

#pragma mark -
#pragma mark 輸入代碼取出時區名稱  

-(NSString *)symbol_convert_timeZone:(NSString *)symbol{
    Convert_timeZoneName *ctn=[[[Convert_timeZoneName alloc] init] autorelease];
                      
    NSString *datasourcea=datasource;
    
    if ([datasourcea isEqualToString:id_Yahoo_WEB]) {
        
        return [ctn Yahoo_Symbol_converTo_timeZoneWithName:symbol];
    }
    else if ([datasourcea isEqualToString:id_Yahoo_Mobile]) {
        return [ctn Yahoo_Symbol_converTo_timeZoneWithName:symbol];
        
        
    }
    else if ([datasourcea isEqualToString:id_MultiServer_GY]) {
        return [ctn Yahoo_Symbol_converTo_timeZoneWithName:symbol];
        
        
    }
    
    else if ([datasourcea isEqualToString:id_Google]) {
        return [ctn  Google_Symbol_converTo_timeZoneWithName:symbol]; 
        
    }
    else if ([datasourcea isEqualToString:id_Bloomberg]) {
        
        return [ctn  Bloomberg_Symbol_converTo_timeZoneWithName:symbol];         
    }    
    else {
        return nil;
    }
    
    
}

#pragma mark -
#pragma mark 整合報價表與走勢圖上的計算方法
-(void)combine_calculate_method_table_chart{
    
    NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults]; 
   
    NSMutableArray *old_Combine=[prefs objectForKey:Defaults_Calculate_method_combine];
    
    //整合
    NSLog(@"計算方法 報價表=%@",[prefs objectForKey:Defaults_Calculate_method_table_click] );
    NSLog(@"計算方法 走勢圖=%@",[prefs objectForKey:Defaults_Calculate_method_chart_click ] );
    NSLog(@"計算方法 排序=%@",[prefs objectForKey:Defaults_Calculate_method_sort_click ] );
    NSLog(@"計算方法 輸出=%@",[prefs objectForKey:Defaults_Calculate_method_output_click ] );
    
    NSMutableArray *combine_calculate=[[NSMutableArray alloc] init];
    
    for (NSString *ds in [prefs objectForKey:Defaults_Calculate_method_table_click]) {
        if ([combine_calculate indexOfObject:ds]==NSNotFound) {
            [combine_calculate addObject:ds];
        }
        
    }
    for (NSString *ds in [prefs objectForKey:Defaults_Calculate_method_chart_click]) {
        if ([combine_calculate indexOfObject:ds]==NSNotFound) {
            [combine_calculate addObject:ds];
        }
        
    }
    for (NSString *ds in [prefs objectForKey:Defaults_Calculate_method_sort_click]) {
        if ([combine_calculate indexOfObject:ds]==NSNotFound) {
            [combine_calculate addObject:ds];
        }
        
    }
    for (NSString *ds in [prefs objectForKey:Defaults_Calculate_method_output_click]) {
        if ([combine_calculate indexOfObject:ds]==NSNotFound) {
            [combine_calculate addObject:ds];
        }
        
    }
    
    
    NSLog(@"計算方法 三種整合 舊=%@",old_Combine );
    NSLog(@"計算方法 三種整合 最新=%@",combine_calculate );
    
    [prefs setObject:combine_calculate forKey:Defaults_Calculate_method_combine];
    [prefs synchronize];
    
    [self  setHave_to_calculate_history_serial_indicator_signal:combine_calculate];    

    //判斷是否需要重新計算
    if (old_Combine) {
        
        
        BOOL havetoreculate;
        havetoreculate=NO;
       
        for (NSString *newc in combine_calculate ) {
        
            if ([old_Combine indexOfObject:newc]==NSNotFound) {
                //如果有一個新的計算方法在舊的方法裡沒有找到 就必須重新計算
                havetoreculate=YES;
            }
            
        }

        if (havetoreculate==YES) {
            NSLog(@"必須重新計算");
            [self re_calculate_all_history_object_indicator_signal];            
        }
        else {
            NSLog(@"不必須重新計算");
        }
        
    }
       
    
    [combine_calculate release];
    


}
 



@end
